UVa 12563
来源:互联网 发布:猎头 数据库 建立 编辑:程序博客网 时间:2024/05/07 04:00
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=10000;int n,t,time;int a[55],dp[55][maxn],len[55][maxn];int main(){ int kase=1; scanf("%d",&t); while(t--) { memset(dp,0,sizeof(dp)); memset(len,0,sizeof(len)); scanf("%d%d",&n,&time); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=n;i>=1;i--) { for(int j=0;j<=time;j++) { dp[i][j]=(i==n)?0:dp[i+1][j]; len[i][j]=len[i+1][j]; if(j>=a[i]) { if(dp[i][j]<dp[i+1][j-a[i]]+1) { dp[i][j]=dp[i+1][j-a[i]]+1; len[i][j]=len[i+1][j-a[i]]+a[i]; } else if(dp[i][j]==dp[i+1][j-a[i]]+1) len[i][j]=max(len[i+1][j],len[i+1][j-a[i]]+a[i]); } } } int maxs=-1; for(int i=time-1;i>=0;i--) { if(dp[1][i]==dp[1][time-1]) { if(maxs<len[1][i]) maxs=len[1][i]; } } printf("Case %d: %d %d\n",kase++,dp[1][time-1]+1,maxs+678);//此处的dp[1][time]换成了dp[1][time-1]才能正确的。 } return 0;}
这个题目主要就是要考虑好题目的要求,这个和一般的01背包问题稍有不同,可以算是一个变形。
该博主的分析就是相当的准确 http://blog.csdn.net/u013480600/article/details/40376143
KTV里面有n首歌曲你可以选择,每首歌曲的时长都给出了. 对于每首歌曲,你最多只能唱1遍. 现在给你一个时间限制t (t<=10^9) , 问你在最多t-1秒的时间内可以唱多少首歌曲num , 且最长唱歌时间是多少time (time必须<=t-1) ? 最终输出num+1 和 time+678 即可.
注意: 你需要优先让歌曲数目最大的情况下,再去选择总时长最长的.
分析:
其实本题本质上就是一个标准的01背包问题. 问你<=t-1时间内最多可以选择哪些歌曲使得 (数据1,数据2) 最优. 这里的数据1是歌曲数目, 数据2是歌曲总时长, 且数据1优先.
一般我们做的01背包问题都是问你<=t-1的时间内, 最多选择哪些歌曲使得歌曲数目最多 或 总时间最长. 但是本题需要同时考虑两个最优条件, 那么该怎么做呢?
我们令dp[i][j]==x 表示当决策完全前i个物品后(选或不选), 所选的总歌曲时长<=j时, 所得到的最优状态为x. (这里的x就不是平时我们所说的最长时间或最多歌曲数目了)
怎么理解最优状态为x这个事实呢? 假设有两种选择前i个歌曲的方法能使得决策完前i个物品且总时长<=j时的状态分别为x1 和x2.
那么如果x1状态的歌曲数目> x2状态的歌曲数目, 那么明显x1状态更优. 所以dp[i][j]应==x1.
如果x1状态的歌曲数目与x2的相等, 但是x2状态的时长 > x1状态时长, 那么此时x2状态更优. 所以dp[i][j]应==x2.
经过上面的分析,我们可以用一个(具有歌曲数和总时长双属性的)结构体来表示一个状态. 且可以得到下面状态转移公式:
dp[i][j] = 最优( dp[i-1][j] , 在dp[i-1][j-t[i]]的基础上选择第i首歌后得到的新状态tmp )
所有dp初始化为0即可. 最终我们所求为dp[n][max_time]
最后还有一个问题就是t<=10^9.我们不可能循环判断j到10^9. 其实一共50首歌曲, 每首歌曲最多180秒, 所以我们求出所有歌曲的时长和sum(sum<=50*180==9000).
如果t-1>=sum, 那么明显所有歌曲都能被选一遍.
如果t-1<sum,那么明显我们需要遍历到dp[i][t-1]为止.
程序实现用的滚动数组,所以dp只有[j]这一维.
- uva-1025、uva-437、uva-1347、uva-116、uva-12563
- uva 12563
- UVa 12563
- UVA-12563
- uva 12563
- uva 12563劲歌金曲
- UVa 12563 dp 背包
- UVA 12563 01背包
- UVA-12563 01背包
- uva
- UVA
- UVA
- UVA
- uva
- UVA
- UVA
- UVA
- UVA
- POJ 3104 Drying
- java-并发-解决锁竞争的问题
- 笑一笑
- 【OpenCV笔记 12】OpenCV边缘检测之canny算子
- LeetCode-121:Best Time to Buy and Sell Stock
- UVa 12563
- Objective-C & Sprite Kit太空历险记 : 3. 军官训练营——控制你的代码
- Block(五)heap-stack-memory
- 简记:一次修复CentOS7因卸载多余内核后引起启动文件丢失及其后续问题的过程
- poj 2752 KMP(next数组的运用)
- 数字签名是什么?
- php 字符串长度的解释
- java小工具CommonUtils
- Objective-C & Sprite Kit太空历险记 : 4. 打造作战单位——面向对象编程(上)