UVA12563 01背包

来源:互联网 发布:淘宝店铺关键词排名 编辑:程序博客网 时间:2024/04/29 21:19

题意

输入t个样例,每个样例第一行包含两个数字n,t,n代表歌曲数目,t代表剩余时间。第二行n个数字代表n首歌曲的时间。求时间小于t的情况下,最多可以唱多少首歌曲,并且时间要尽量长。

题解

题中说明每首歌曲不超过3分钟,即180秒,并且题中说明总时间不超过n+1首歌曲(即180*n+678秒,因为最后要唱一首678秒的歌曲)。因此,该问题可转化为简单的01背包问题。套用01背包模板即可。

注意事项

题中要求唱歌时间尽量长,而动态规划记录过程并不是很方便,因此这里用到了一个小技巧。在动态规划决策阶段,只有一首歌曲恰好唱完时(j==v||f[j-v]>0),才进行变化。这样,在最后阶段,可以根据最大歌曲量寻找到最长歌唱时间。

代码

#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int f[10000];int a[100];int main(){    //freopen("d://input.txt","r",stdin);    //freopen("d://output.txt","w",stdout);    int v,w,c,n;    int kase;    int ks=0;    scanf("%d",&kase);    while(kase--){        ks++;        memset(f,0,sizeof(f));        scanf("%d%d",&n,&c);        c--;        int ans=0;        for(int i=1;i<=n;i++){            scanf("%d",&v);            a[i]=v;            for(int j=c;j>=v;j--){                if(j==v||f[j-v]>0){                    f[j]=max(f[j],f[j-v]+1);                    ans=max(ans,f[j]);                }            }        }        int t=0;        for(int i=c;i>=0;i--){            if(f[i]==ans){                t=i;                break;            }        }        if(ans==0)            printf("Case %d: %d %d\n",ks,ans+1,678);        else            printf("Case %d: %d %d\n",ks,ans+1,t+678);    }    return 0;}
0 0
原创粉丝点击