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

总的来说就是价值为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;
}
上一篇:阿里分布式服务框架Dubbo的架构总结


下一篇:递归与非递归打印乘法口诀表--Scala(指令式、函数式思维练习)