# 劲歌金曲

【题目链接】劲歌金曲

【题目类型】01背包

&题解:

题意:求在给定时间内,最多能唱多少歌曲,在最多歌曲的情况下,使唱的时间最长。
该题类似于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的就是在最多歌曲情况下的最长时间。
参考于:http://blog.csdn.net/yanzheshi/article/details/47086461

这是01背包的变形,但上面的想法确实很巧妙,也就是巧妙在定义f数组所表示的状态的时候,真的应该学习下这种分析问题的过程。
【时间复杂度】O(n*10000)

&代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
#define cle(a,val) memset(a,(val),sizeof(a))
#define SI(N) scanf("%d",&(N))
#define SII(N,M) scanf("%d %d",&(N),&(M))
#define SIII(N,M,K) scanf("%d %d %d",&(N),&(M),&(K))
#define rep(i,b) for(int i=0;i<(b);i++)
#define rez(i,a,b) for(int i=(a);i<=(b);i++)
#define red(i,a,b) for(int i=(a);i>=(b);i--)
const ll LINF = 0x3f3f3f3f3f3f3f3f;
#define PU(x) puts(#x);
#define PI(A) cout<<(A)<<endl;
#define DG(x) cout<<#x<<"="<<(x)<<endl;
#define DGG(x,y) cout<<#x<<"="<<(x)<<" "<<#y<<"="<<(y)<<endl;
#define DGGG(x,y,z) cout<<#x<<"="<<(x)<<" "<<#y<<"="<<(y)<<" "<<#z<<"="<<(z)<<endl;
#define PIar(a,n) rep(i,n)cout<<a[i]<<" ";cout<<endl;
#define PIarr(a,n,m) rep(aa,n){rep(bb, m)cout<<a[aa][bb]<<" ";cout<<endl;}
const double EPS = 1e-9 ;
/* //////////////////////// C o d i n g S p a c e //////////////////////// */
const int MAXN = 10000 + 9 ;
int K,n,t,a,f[MAXN];
void Solve()
{
cle(f,0);
int ma=0;
SII(n,t); t--;
rep(i,n){
SI(a);
red(j,t,a){
if (f[j-a]||j==a){
f[j]=max(f[j],f[j-a]+1);
ma=max(ma,f[j]);
}
}
}
// PIar(f,t+3)
int ti=t;
while(f[ti]!=ma) ti--;
if (ma==0){
printf("Case %d: %d %d\n",++K,1,678 );
}
else {
printf("Case %d: %d %d\n",++K,ma+1,ti+678 );
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("1.in", "r", stdin);
freopen("1.out","w",stdout);
#endif
//iostream::sync_with_stdio(false);
//cin.tie(0), cout.tie(0);
int T;cin>>T;while(T--)
Solve();
return 0;
}

UVA 12563 劲歌金曲(01背包)的更多相关文章

  1. UVa 12563 劲歌金曲(0-1背包)

    https://vjudge.net/problem/UVA-12563 题意: 在一定的时间内连续唱歌,最后一首唱11分钟18秒的劲歌金曲,问最多能长多长时间. 思路: 0-1背包问题,背包容量为t ...

  2. UVa 12563 劲歌金曲 刘汝佳第二版例题9-5;

    Problem J Jin Ge Jin Qu [h]ao (If you smiled when you see the title, this problem is for you ^_^) Fo ...

  3. UVA.10130 SuperSale (DP 01背包)

    UVA.10130 SuperSale (DP 01背包) 题意分析 现在有一家人去超市购物.每个人都有所能携带的重量上限.超市中的每个商品有其相应的价值和重量,并且有规定,每人每种商品最多购买一个. ...

  4. UVA 562 Dividing coins --01背包的变形

    01背包的变形. 先算出硬币面值的总和,然后此题变成求背包容量为V=sum/2时,能装的最多的硬币,然后将剩余的面值和它相减取一个绝对值就是最小的差值. 代码: #include <iostre ...

  5. UVA 624 CD(01背包+输出方案)

    01背包,由于要输出方案,所以还要在dp的同时,保存一下路径. #include <iostream> #include <stdio.h> #include <stri ...

  6. UVA 562 Dividing coins (01背包)

    //平分硬币问题 //对sum/2进行01背包,sum-2*dp[sum/2] #include <iostream> #include <cstring> #include ...

  7. UVA 624 CD(DP + 01背包)

    CD You have a long drive by car ahead. You have a tape recorder, but unfortunately your best music i ...

  8. uva 624 CD (01背包)

      CD  You have a long drive by car ahead. You have a tape recorder, but unfortunately your best musi ...

  9. UVA 624 CD[【01背包】(输出路径)

    <题目链接> 题目大意: 你要录制时间为N的带子,给你一张CD的不同时长的轨道,求总和不大于N的录制顺序 解题分析: 01背包问题,需要注意的是如何将路径输出. 由于dp时是会不断的将前面 ...

随机推荐

  1. ed编辑器使用

    evilxr@IdeaPad:/tmp$ ed aa.c 0 a enter another words hello nice www.evilxr.com . w aa.c 46 q a 表示添加内 ...

  2. appium简明教程(6)——启动appium及android模拟器

    一般情况下,我们都从命令行启动appium. windows下,dos命令窗口输入 appium 如果该命令报错,那么请重装appium npm install -g appium 如果安装出错,请自 ...

  3. flash全屏输入模式

    params.allowscriptaccess = "sameDomain"; params.allowfullscreen = "true"; params ...

  4. __LINE__ __DATE__ __FILE__ __TIME__ 等宏定义解释

    Names the predefined ANSI C and Microsoft C++ implementation macros. The compiler recognizes predefi ...

  5. asm单机dg dbca报错ORA-01031 CRS-2676,rman restore主库控制文件报错ORA-15081

    dg-> ll $ORACLE_HOME/bin/oracle -r-xr-s--x 1 oracle asmadmin 210824714 Nov 20 16:41 /u01/app/orac ...

  6. Java中的简单工厂模式

    举两个例子以快速明白Java中的简单 工厂模式: 女娲抟土造人话说:“天地开辟,未有人民,女娲抟土为人.”女娲需要用土造出一个个的人,但在女娲造出人之前,人的概念只存在于女娲的思想里面.女娲造人,这就 ...

  7. 如何用ABBYY把PDF转换成PPT

    在电子科技迅速发展的今天,文件格式转换并不是什么稀罕事,因为现在都是电子化办公,出现很多文件格式,但是不同的场合需要的格式不同,所以常常需要进行文件格式的转换.PDF转换成PPT也是众多文件格式转换中 ...

  8. unity, 保存prefab时material丢失问题

    在程序运行时用replacePrefab(gameObj,prefab)或createPrefab(gameObj,prefab)保存prefab,遇到保存出来的prefab中material丢失的问 ...

  9. ECS修改默认端口22及限制root登录

    首先要创建一个用户,用系统默认的www用户也可以(这里不介绍如何创建用户) 接下来要修改www的密码: passwd www 执行此命令后会让你输入两次密码.这样就设置好了. 然后进入: vi /et ...

  10. 利用Swift之协议语法实现页面间的传值功能

    随着Swift 新开发语言的发布,又随着Xcode6.0.1的正式发布,利用swift编写iOS代码迫在眉睫,笔者在使用Objective-C开发近三年以来,对这种优雅的语法深感赞叹,下面我将对比式的 ...