zoukankan      html  css  js  c++  java
  • 紫书 例题 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
    ", ++kase, ans, time);
    	}
    	
    	return 0;
    }
  • 相关阅读:
    洛谷 P3392 涂国旗
    CODEVS 1066/洛谷 P1514引水入城
    POJ 1286 Necklace of Beads(项链的珠子)
    CODEVS 1138 聪明的质监员
    洛谷 P1241 括号序列
    C++之路进阶——codevs2313(星际竞速)
    C++之路进阶——codevs2366(朋友圈)
    c++之路进阶——hdu3507(Print Article)
    C++之路进阶——codevs2404(糖果)
    C++之路进阶——codevs4655(序列终结者)
  • 原文地址:https://www.cnblogs.com/sugewud/p/9819457.html
Copyright © 2011-2022 走看看