当前位置: 代码迷 >> 综合 >> 紫书 例题 9-5 UVa 12563 ( 01背包变形)
  详细解决方案

紫书 例题 9-5 UVa 12563 ( 01背包变形)

热度:41   发布时间:2023-09-20 20:16:56.0

总的来说就是价值为1,时间因物品而变,同时注意要刚好取到的01背包
(1)时间方面。按照题意,每首歌的时间最多为t + w - 1,这里要注意。
同时记得最后要加入时间为678的一首歌曲
(2)这里因为要输出时间,也就是重量,那么这个时候初始化就要注意了。
因为如果只是输出价值的话就全部初始化为0,但是要输出重量,那就意味着
当前这个时间是恰好由几首歌组合,那么初始化的时候就要注意全部初始化为
-1,f[0] = 0,同时判断条件要f[j-w] != -1,这里要注意
(3)这里时间很坑!我一开始看到10的9次方肯定超时,后来紫书上写到最多
也就180n+678,10的9次方是吓唬你的,实际上t最大只在一万左右,是完全
可以的。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std;const int MAXN = 11234;
int f[MAXN], w, t, n, m;int main()
{int T, kase = 0;scanf("%d", &T);while(T--){scanf("%d%d", &n, &t);memset(f, -1, sizeof(f)); //初始化注意 f[0] = 0;int ans = -1, time = 0;REP(i, 0, n + 1) {if(i == n) w = 678; //要多一件物品 else scanf("%d", &w);for(int j = t + w - 1; j >= w; j--) //时间随物品而定 {if(f[j-w] != -1)              //不要漏了 f[j] = max(f[j], f[j-w] + 1);ans = max(f[j], ans);}}for(time = MAXN - 1; f[time] != ans; time--); //最长时间 printf("Case %d: %d %d\n", ++kase, ans, time);}return 0;
}