UVA12563 0-1背包变形

题目链接点击打开链接

题意:KTV里面有n首歌曲你可以选择,每首歌曲的时长都给出了. 对于每首歌曲,你最多只能唱1遍. 现在给你一个时间限制t (t<=10^9) , 问你在最多t-1秒的时间内可以唱多少首歌曲num , 且最长唱歌时间是多少time (time必须<=t-1) ? 最终输出num+1 和 time+678 即可.

       注意: 你需要优先让歌曲数目最大的情况下,再去选择总时长最长的.

分析:题意是在小于t的时间内,选择哪些歌曲可使得所选歌曲数目最多,在此前提下,所选歌曲总时间越长越好。

设DP(i,j)表示“把前i首歌曲装到时间容量为j的背包中的最大总重量(重量包含两个属性:歌曲数目和歌曲长度)”。

状态转移方程  dp[i][j] =max( dp[i-1][j],  在dp[i-1][j-t[i]]的基础上选择第i首歌后得到的新状态tmp)

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int maxn = 10000 ;
int a[55] ;
struct song
{
    int number ;
    int length ;
}S[52][maxn];

bool operator > (const song &A , const song &B)
{
    if(A.number == B.number) return A.length > B.length ;
    else return A.number > B.number ;
}



int main()
{
    //freopen("a.txt" , "r" , stdin) ;
    int T , n , t , kase = 0 ;
    scanf("%d" , &T) ;
    while(T --)
    {
        scanf("%d%d" , &n , &t) ;
        for(int i = 1 ; i <= n ; i++)
            scanf("%d" , &a[i]) ;
        memset(S , 0 , sizeof(S)) ; //初始化
        for(int i = 1 ; i <= n ; i++)
        {
            for(int j = 0 ; j <= t ; j ++)
            {
                if(i == 1) { S[i][j].number = 0 ; S[i][j].length = 0; }
                else S[i][j] = S[i - 1][j] ;
                if(j > a[i]) //注意不能取等于
                {
                    song t ;
                    t.number = S[i - 1][j - a[i]].number + 1 ;
                    t.length = S[i-1][j-a[i]].length + a[i] ;
                    if(t > S[i][j]) S[i][j] = t ;
                }
                //printf("i=%d j=%d %d %d\n" ,i , j , S[i][j].number , S[i][j].length) ;
            }
        }
        //printf("\n") ;
        printf("Case %d: %d %d\n" , ++kase , S[n][t].number + 1 , S[n][t].length + 678) ;
    }
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值