12563 - Jin Ge Jin Qu hao(DP)

本文分享了一个动态规划问题的解决过程,作者通过两小时的努力找到了最优解,并总结了解题经验。文章详细介绍了如何正确理解题目要求及如何设定状态转移方程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自己花了两个小时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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值