uva12563 Jin Ge Jin Qu

本文通过一个具体的01背包问题实例,详细介绍了如何使用C++实现动态规划算法来解决该问题,并展示了完整的代码实现过程。

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

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxx = 180 * 55;
int t[55];//题目所给的歌的每个时长

struct Node{
    int num, time;//歌的数量和时长
}dp[maxx];

int main()
{
    int l;
    int n, len, sum = 0;//len控制时长,sum为了判断所给的歌的总时长
    int max_time;//为了判断所给len时长与sum大小
    int cnt = 1;
    scanf("%d", &l);
    while(l--){
        scanf("%d%d", &n, &len);
        memset(dp, 0, sizeof(dp));
        memset(t, 0, sizeof(t));
        for(int i = 1; i <= n; i++) {scanf("%d", &t[i]); sum += t[i];}
        max_time = min(sum, len - 1);//最多也是时长限制-1
        for(int i = 1; i <= n; i++){
            for(int j = max_time; j >= t[i]; j--){
                Node s;    //这里用Node  其实就是降维度的一个写法,从max_time to t[i]这种写法可以降维度其实和最简单的01背包相同
                s.num = dp[j-t[i]].num + 1;//这里一定记得搞清楚是”前“i件物品(歌)的总和,自己不懂可以推一下
                s.time = dp[j-t[i]].time + t[i];
                if(dp[j].num < s.num){//这个题歌的数量优先 dp[j]表示当前容量下的个数,s.num表示前i首歌的总个数
                    dp[j].num = s.num;
                    dp[j].time = s.time;
                }
                else if(dp[j].num == s.num && dp[j].time < s.time){//相同个数的歌需要保证最长时间
                    dp[j].num = s.num;
                    dp[j].time = s.time;
                }
            }
        }
        cout <<"Case " << cnt++ << ": " << dp[max_time].num + 1 << " " << dp[max_time].time + 678 << endl << max_time;//这里+1的原意是结构体初始化为0
        //其实博主刚开始很诧异为什m最终最多的个数会更新到max_time上,这是由于第一个if,自己不懂过程的一定自己在纸上推一下,懂过程以后代码就显得简单了
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值