12563 - Jin Ge Jin Qu hao(DP)

来源:互联网 发布:大数据的书 编辑:程序博客网 时间:2024/06/05 10:41

自己花了两个小时A出来的感觉就是不一样啊,学习DP建议大家多煎熬一点,好好思考状态是如何转移的。

不过这道题我一开始理解错题意了,不然也不会浪费这么长时间 。 一开始以为是背包问题,后来才发现要求使得唱的曲目尽量多,在此前提下尽量晚离开KTV,我恰好弄颠倒了。

这样我们就不难得出递推方程 : 因为每首曲目只能唱一遍,所以这就使递推变得有序了~ 那么我们设cnt[i][j]表示唱前i首歌中的若干,且总时间不超过j 的最大歌曲数目 。

那么cnt[i][j] = max(cnt[i-1][j],cnt[i-1][j-a[i]] + 1);    因为还要使总时间尽量长,所以当cnt[i][j] == cnt[i-1][j-a[i]] + 1 时,d[i][j] = max(d[i][j],d[i-1][j-a[i]] + a[i]);

细节参见代码:

#include<bits/stdc++.h>using namespace std;const int maxn = 55;int T,n,t,Case = 0,d[maxn][180*maxn + 678],a[maxn],cnt[maxn][180*maxn + 678];int main() {    scanf("%d",&T);    while(T--){        scanf("%d%d",&n,&t);        for(int i=1;i<=n;i++) scanf("%d",&a[i]);        for(int i=1;i<=n;i++) {            for(int j=0;j<=t;j++) {                cnt[i][j] = (i == 1 ? 0 : cnt[i-1][j]);                d[i][j] = (i == 1 ? 0 : d[i-1][j]);                if(j > a[i]) {                    if(cnt[i][j] < cnt[i-1][j-a[i]] + 1) {                        cnt[i][j] = cnt[i-1][j-a[i]] + 1;                        d[i][j] = d[i-1][j-a[i]] + a[i];                    }                    else if(cnt[i][j] == cnt[i-1][j-a[i]] + 1) {                        d[i][j] = max(d[i][j],d[i-1][j-a[i]] + a[i]);                    }                }            }        }        printf("Case %d: %d %d\n",++Case,cnt[n][t]+1,d[n][t]+678);    }    return 0;}


1 0
原创粉丝点击