uva12563(01背包)
来源:互联网 发布:武汉育才行知小学校长 编辑:程序博客网 时间:2024/05/17 04:58
转载自:大神博客
题目大意:
求在给定时间内,最多能唱多少歌曲,在最多歌曲的情况下,使唱的时间最长。
题目分析:
该题类似于01背包问题,可用01背包问题的解题思路来求,每个歌曲相当于物品,歌曲的长度相等于物品重量,每个歌曲的“价值”为1。由于金歌劲曲时间最长,所以最后要留至少1秒时间开始唱金歌劲曲,所以计算t-1时间内最多唱的歌曲和时间,最终答案为歌曲数加1,时间加上金歌劲曲的时间。这里我使用滚动数组计算这个值, 用len记录t-1。
需要注意的是,由于要求是连续唱歌,且要求在最多歌曲数的情况下时间最长,如果按普通的背包存储,很难得到最长时间,因为f[len] 只存储了最多的歌曲数,但并不知道这些歌曲到底唱了多少时间。假设最多歌曲数为num, 唱num首歌曲最少时间为tmin, 那么数组中从f[tmin]到f[len]都等于num,我们无法得知唱num首歌的最大时间。比如说len = 10, t[1] = 5, t[2] = 8, 那么f[5] 到 f[10] 都等于1, 无法知道唱从5到10哪个是唱1首歌的最长时间。如何处理呢?
这里需要用到一个技巧:对决策进行一定的限定!在计算某个时间最多唱的歌曲时,必须是该时间内恰好唱完这些歌,时间多了不行。即f[j]表示的是在j 的时间恰好用完的情况下最多能唱多少首歌。比如上面的例子只有f[5] 和f[8]等于1,其他的都等于0。这样的话处理时先算出最多唱的歌曲数 num,然后从j = len开始遍历数组f, 第一个等于num的就是在最多歌曲情况下的最长时间。
代码:
#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int MAXN = 10000;int f[MAXN], t[55];int main(){ int T, n, cas, i, j, len, ma; scanf("%d", &T); for(cas = 1; cas <= T; cas++) { scanf("%d%d", &n, &len); len--; //留最后一秒开始唱金歌劲曲 for(i = 1; i <= n; i++) scanf("%d", &t[i]); memset(f, 0, sizeof(f)); ma = 0; //记录最多歌曲数。 for(i = 1; i <= n; i++) { for(j = len; j >= t[i]; j--) { if(f[j - t[i]] >= 1|| j == t[i]) //在j时间内可以唱完第i首歌。 { f[j] = max(f[j], f[j - t[i]] + 1); ma = max(ma, f[j]); } } } for(i = len; f[i] != ma; i--); //寻找唱最多歌情况下,时间最长的那个 if(ma == 0) //在给定时间内无法唱完任何一首歌 printf("Case %d: %d %d\n", cas, 1, 678); else printf("Case %d: %d %d\n", cas, 1 + ma, i + 678); } return 0;}
自己实现的代码:
#include <stdio.h>#include <iostream>#include <algorithm>#include <bits/stdc++.h>using namespace std;const int maxn=1000000;int T,n,t;int a[maxn],num[maxn];int main(){// freopen("in.txt","r",stdin);// freopen("out.txt","w",stdout); cin>>T; for(int Case=1;Case<=T;Case++){ int maxsong=0; cin>>n>>t; for(int i=0;i<=t;i++){ num[i]=0; } for(int i=1;i<=n;i++){ cin>>a[i]; } for(int i=1;i<=n;i++){ for(int j=t-1;j>=a[i];j--){ if(num[j-a[i]]||j==a[i]){ num[j]=max(num[j],num[j-a[i]]+1); maxsong=max(maxsong,num[j]); } } } int i; for(i=t-1;num[i]!=maxsong&&i;i--); if(maxsong==0) i=0; cout<<"Case "<<Case<<": "<<maxsong+1<<" "<<i+678<<endl; } return 0;}
阅读全文
0 0
- uva12563(01背包)
- UVA12563 01背包
- UVA12563 01背包的变形
- UVA12563 - Jin Ge Jin Qu hao(01背包)
- UVA12563: Jin Ge Jin Qu hao(类01背包)
- UVA12563 0-1背包 (一位数组)
- UVa12563--Jin Ge Jin Qu hao DP(01背包)
- UVa12563 -Jin Ge Jin Qu hao(DP) 01背包
- UVA12563 Jin Ge Jin Qu hao(DP, 背包+技巧)
- UVA12563 0-1背包变形
- uva12563
- UVA12563
- uva12563
- UVa12563
- UVA12563 Jin Ge Jin Qu hao(背包问题)
- 【UVa12563劲歌金曲】0-1背包+小技巧
- 【紫书】(UVa12563)Jin Ge Jin Qu hao
- 背包问题(01背包,完全背包,多重背包)
- 你有4张卡片,每张卡片从1到9的数字,通过*,/,+,
- (二十三)websocket
- php-fpm的设置
- 7-64 最长对称子串
- Struts2 拦截器配置
- uva12563(01背包)
- 更改Oracle表空间名
- 各种流行的编程风格 你属于哪一种?
- 两种常用的选择排序算法--简单选择排序、堆排序
- JAVA | 21
- 曾经最强浏览器王者归来!火狐量子 vs 谷歌浏览器:哪一个更快呢?
- 浏览器缓存和HTTP条件请求
- C# 浅谈ThreadPool -- 中篇(ThreadPoolMrg)
- cmd下编译执行arm汇编文件