UVA12563 Jin Ge Jin Qu hao(01背包)

本题vjudge链接

  • 大致题意:在KTV里,如果还剩下1秒的时间,则可以点一首更长的歌,因为他会播放完最后一首歌才停止,现在给你剩下的时间 m m m n ( n ≤ 50 ) n(n \le 50) n(n50)首歌,每首歌的时长 t 1 , t 2 , t 3 … … t n t_1, t_2, t_3 ……t_n t1,t2,t3tn,现让你算出在剩余的时间内能唱的歌的最大数量,然后利用空出来的时间最后再点一首长为678秒的歌,输出能唱的最大数量,对应的时间
  • 简单的分析:
    • 题目中说最后会点一首678秒的歌来延长时间,则策略就是计算在不超过 m − 1 m - 1 m1时间里选最多的歌
    • 读一读上面的一句话,是不是感觉很想01背包?是的就是01背包问题,每个物品的价值默认是1了(一首歌嘛)
    • 题目中说 m ≤ 1 0 9 m \le 10^9 m109,其实并没有这么大,~~我一开始也很苦恼这怎么建数组,~~后来发现其实并没有这么大,他说n + 1首歌的时长严格大于剩余的时长,并且每一首歌不会超过3分钟,这么算的话 180 × 50 + 678 = 9678 180 \times 50 + 678 = 9678 180×50+678=9678,固数组完全够开
    • 值得注意的是这题计算在选歌的数量多的前提下最后尽量晚地结束KTV,这就需要讨论了,一开始被这个搞得十分地晕,冷静下来后发现一个if是不够的,于是就特判3次
      • 首先如果当前抉择的歌曲数量还没之前算的多,直接跳过
      • 如果当前抉择的歌曲数量严格比之前算的还多,则更新歌曲数量和时间总长度
      • 如果当前抉择的歌曲数量和之前算的一样多,则还要判断当前抉择的时长是严格比上次算还多,则更新时间总长度
    • 具体看代码
#include <cstring>
#include <cstdio>
#include <algorithm>

using namespace std;

int n, t, dp[10010], m, kase = 0, sum[10010];

void solve() {
    scanf("%d%d", &n, &m);
    memset(dp, 0, sizeof dp);
    memset(sum, 0, sizeof sum);
    for (int i = 0; i < n; i++) {
        scanf("%d", &t);
        for (int j = m; j > t; j--) {
            if (dp[j] > dp[j - t] + 1) continue;//特判1
            if (dp[j] < dp[j - t] + 1) {        //特判2
                dp[j] = dp[j - t] + 1;
                sum[j] = sum[j - t] + t;
            } else if (sum[j] < sum[j - t] + t){//特判3
                sum[j] = sum[j - t] + t;
            }
        }
    }
    printf("Case %d: %d %d\n", ++kase, dp[m] + 1, sum[m] + 678);
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("D:/MYCODE/vsCode-c/test.in", "r", stdin);
    freopen("D:/MYCODE/vsCode-c/test.out", "w", stdout);
#endif
    int T;
    scanf("%d", &T);
    while (T--) {
        solve();
    }
    return 0;
}

原地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值