Jin Ge Jin Qu hao UVA

来源:互联网 发布:淘宝用红包退款 编辑:程序博客网 时间:2024/06/07 08:29

题目链接:点我

题目大意求给定时间内能唱的最多数量的歌曲,以及时间

思路:

一开始以为是求最大时间,然后疯狂wa,又看了遍题目才知道是求最大数量,这道题明显就是一道背包dp,定义状态cnt[i][j]为前i首歌在j时间内,最大能唱的歌曲数量因为还要算算出时间,其实我们有两种做法,可以通过记录路径,然后求出时间,但是这样子还是挺麻烦的,我们可以通过在开一个dp[i][j]与cnt同步更新,有一点要注意,当cnt相同时没我们要更新出最大的时间(思路还是比较简单的)

ac代码

#include<cstdio>#include<vector>#include<cstring>#include<map>#include<iostream>#include<sstream>#include<queue>#define LL long long#define INF 0x3f3f3f3fusing namespace std;const int maxn = 50*180+678+456;int dp[55][maxn];int cnt[55][maxn];int cost[55];int n;int t;int T;int main(){    int kase = 1;    cin>>T;    while(T--)    {cin>>n>>t;        for(int i = 1 ;i<=n;i++)        {            cin>>cost[i];        }        memset(dp,-INF,sizeof(dp));        memset(cnt,0,sizeof(cnt));        for(int i = 0;i<=t;i++)        {            dp[0][i] = 0;        }        for(int i = 1 ;i<=n;i++)        {            for(int j = 0;j<=t;j++)            {                dp[i][j] = dp[i-1][j];                cnt[i][j] = cnt[i-1][j];                if(j>=cost[i])                {                    if(cnt[i][j]<cnt[i-1][j-cost[i]]+1)                    {                        dp[i][j] = dp[i-1][j-cost[i]]+cost[i];                        cnt[i][j] = cnt[i-1][j-cost[i]]+1;                    }                    else if(cnt[i][j]==cnt[i-1][j-cost[i]]+1)                    {                        dp[i][j] = max(dp[i-1][j-cost[i]]+cost[i],dp[i][j]);                    }                }            }        }        int first = cnt[n][t];        int ans = dp[n][t];        int ok = 0;        cout<<"Case "<<kase++<<": "<<cnt[n][t-1]+1<<' '<<dp[n][t-1]+678<<endl;    }    return 0;}


原创粉丝点击