UVA12563Jin Ge Jin Qu hao(01背包变形:两个条件最优化)
来源:互联网 发布:江南作品集软件下载 编辑:程序博客网 时间:2024/06/06 03:21
来自大佬的博客:http://blog.csdn.net/u013480600/article/details/40376143
UVA 12563 Jin Ge Jin Qu hao(01背包变形:两个条件最优化)
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4008
题意:
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]这一维.
AC代码:#include<iostream>#include<cstring>#include<cstdio>using namespace std;const int maxn = 180*50+5;struct Node{ int num; int time; bool operator < (const Node&other)const { return num < other.num ||(num==other.num && time<other.time); }}dp[maxn];int t[55];int main(){ int T, n, max_t; cin >> T; for(int kase = 1; kase <= T; kase++) { cin >> n >> max_t; memset(dp, 0, sizeof(dp)); int sum = 0; for(int i = 1; i <= n; i++) { cin >> t[i]; sum += t[i]; } max_t = min(sum, max_t-1); for(int i = 1; i <= n; i++) for(int j = max_t; j >= t[i]; j--) { Node tmp; tmp.num = dp[j-t[i]].num + 1; tmp.time = dp[j-t[i]].time + t[i]; if(dp[j] < tmp) dp[j] = tmp; } printf("Case %d: ",kase); printf("%d %d\n",dp[max_t].num+1,dp[max_t].time+678); } return 0;}
- UVA12563Jin Ge Jin Qu hao(01背包变形:两个条件最优化)
- UVA 12563 Jin Ge Jin Qu hao(01背包变形:两个条件最优化)
- UVA 12563 Jin Ge Jin Qu hao 01背包变形
- UVA 12563 Jin Ge Jin Qu hao(01背包变形:两个背包内容)
- uva 12563 Jin Ge Jin Qu hao (01背包变形)
- UVA - 12563 Jin Ge Jin Qu hao (01背包)
- UVA 12563 Jin Ge Jin Qu hao 01背包
- UVa 12563 Jin Ge Jin Qu hao(01背包)
- UVa 12563 - Jin Ge Jin Qu hao(01背包)
- UVa 12563 - Jin Ge Jin Qu hao(01背包)
- UVA12563 - Jin Ge Jin Qu hao(01背包)
- UVaOJ 12563 Jin Ge Jin Qu hao(01背包)
- UVA12563: Jin Ge Jin Qu hao(类01背包)
- UVa12563--Jin Ge Jin Qu hao DP(01背包)
- UVa12563 -Jin Ge Jin Qu hao(DP) 01背包
- Jin Ge Jin Qu hao (01背包学习 紫薯)
- Jin Ge Jin Qu hao
- Jin Ge Jin Qu hao - UVa 12563 dp背包
- 欢迎使用CSDN-markdown编辑器
- 【流媒体技术】流媒体(1)使用nginx搭建流媒体服务器
- 欢迎使用CSDN-markdown编辑器
- github简单使用
- python中的变量可变与不可变
- UVA12563Jin Ge Jin Qu hao(01背包变形:两个条件最优化)
- DOM包裹wrapInner()方法
- Android 设计开发及命名规范
- dump code
- 最常见的Mysql数据库优化、索引优化、字段优化等8个方法
- Java读取数据库的数据并转换为json数据
- LayoutTransition介绍
- android.intent.action.MAIN与android.intent.category.LAUNCHER
- Access中创建SQL语句