题意:KTV里面有n首歌曲你可以选择,每首歌曲的时长都给出了. 对于每首歌曲,你最多只能唱1遍. 现在给你一个时间限制t (t<=10^9) , 问你在最多t-1秒的时间内可以唱多少首歌曲num , 且最长唱歌时间是多少time (time必须<=t-1) ? 最终输出num+1 和 time+678 即可.
注意: 你需要优先让歌曲数目最大的情况下,再去选择总时长最长的.
dp[i][j] 表示 在j分钟内恰好能唱完i首歌
if(dp[i-1][j-time[i]>=0) dp[i][j] =max( dp[i][j] , dp[i-1][j-time[i] + 1 )
只有上j-time[i] 时间内恰好能唱完整数首歌才能转化
其他 dp[i][j]=dp[i-1][j]
#include<bits/stdc++.h>
using namespace std;
int T;
int n,t;
int a[55];
int dp[55][100005];
int dpn[55][100005];
int main()
{
scanf("%d",&T);
int Q=0;
int ans[200];
int ansn[200];
while(T--)
{
Q++;
scanf("%d%d",&n,&t);
int tt=t;
t-=1;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
memset(dp,-1,sizeof(dp));
int ans=0;
for(int i=0;i<=n;i++) dp[i][0]=0;
for(int i=1;i<=n;i++)
{
for(int j=0;j<=t;j++)
{
dp[i][j]=dp[i-1][j];
if(j>=a[i]&&dp[i-1][j-a[i]]>=0)
{
dp[i][j]=max(dp[i][j],dp[i-1][j-a[i]]+1);
}
ans=max(ans,dp[i][j]);
}
}
for(int i=t;i>=0;i--)
{
if(dp[n][i]==ans)
{
printf("Case %d: %d %d\n",Q,ans+1,i+678);
break;
}
}
}
}
//
//2
//3 100
//60 70 80
//3 100
//30 69 70