这道题是普通的0-1背包问题,但是需要注意的是我们要求最多曲目下最长的歌的时间。所以当曲目数相同时,要取最长的时间。
#include <iostream>
#include <bits/stdc++.h>
#define maxn 100000
#define INF 0x3f3f3f3f
using namespace std;
int w[60];
int d[60][maxn];
int ans[60][maxn];
int main() {
int T;
int n;
int t;
int kase = 0;
cin>>T;
while(T--){
cin>>n>>t;
memset(d,-INF, sizeof(d));
memset(ans,0,sizeof(ans));
for(int i = 1;i<=n;i++){
cin>>w[i];
}
for(int i = 0;i<=t-1;i++){
d[0][i] = 0;
}
for(int i = 1;i<=n;i++){
for(int j = 0;j<=t-1;j++){
d[i][j] = d[i-1][j];
ans[i][j] = ans[i-1][j];
if(j>=w[i]){
if(d[i][j]<d[i-1][j-w[i]]+1){
d[i][j] = d[i-1][j-w[i]]+1;
ans[i][j] = ans[i-1][j-w[i]]+w[i];
}
else if(d[i][j]==d[i-1][j-w[i]]+1){
ans[i][j] = max(ans[i][j],ans[i-1][j-w[i]]+w[i]);
}
}
}
}
printf("Case %d: %d %d\n",++kase,d[n][t-1]+1,ans[n][t-1]+678);
}
return 0;
}
/**
2
3 100
60 70 80
3 100
30 69 70
**/
或者d[i][j]表示i阶段剩余j时间还能点的曲目数也一样~
#include <iostream>
#include <bits/stdc++.h>
#define maxn 100000
#define INF 0x3f3f3f3f
using namespace std;
int w[60];
int d[60][maxn];
int ans[60][maxn];
int main() {
int T;
int n;
int t;
int kase = 0;
cin>>T;
while(T--){
cin>>n>>t;
memset(d,-INF, sizeof(d));
memset(ans,0,sizeof(ans));
for(int i = 1;i<=n;i++){
cin>>w[i];
}
for(int i = 0;i<=t-1;i++){
d[n+1][i] = 0;
}
for(int i = n;i>=1;i--){
for(int j = 0;j<=t-1;j++){//j是剩余的时间
d[i][j] = d[i+1][j];
ans[i][j] = ans[i+1][j];
if(j>=w[i]){
if(d[i][j]<d[i+1][j-w[i]]+1){
d[i][j] = d[i+1][j-w[i]]+1;
ans[i][j] = ans[i+1][j-w[i]]+w[i];
}
else if(d[i][j]==d[i+1][j-w[i]]+1){
ans[i][j] = max(ans[i][j],ans[i+1][j-w[i]]+w[i]);
}
}
}
}
printf("Case %d: %d %d\n",++kase,d[1][t-1]+1,ans[1][t-1]+678);
}
return 0;
}
/**
2
3 100
60 70 80
3 100
30 69 70
**/