紫书 例题 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;
}

猜你喜欢

转载自blog.csdn.net/qq_34416123/article/details/81356289
今日推荐