您的位置:首页 > 其它

UVA 12563 劲歌金曲(0-1背包变形~)

2017-09-07 11:01 387 查看
此题有个点要注意:

歌曲数量的优先级高于总时长。所以转移的时候,要判断下一个状态的总数量是否有增长,若有就可以转移,但是若相等,这时再比较时长。

我照着别人写的码但我怎么都过不了。。。怕又是玄学问题?!这里贴三种写法:

#include "bits/stdc++.h"
using namespace std;
int t[55];//记录每首歌的时间
const int maxn = 180*50+5;
struct Node{
int num;//歌曲数量
int time;//歌曲总时间
bool operator < (Node n){
return num < n.num || (num==n.num && time < n.time);
}
}dp[maxn];
int main(int argc, char const *argv[])
{
int C, n, T, i, j;
cin >> C;
int Case = 0;
while(Case++ < C){
cin >> n >> T;
for(i=0;i<n;i++){
cin >> t[i];
}
T--;
memset(dp, 0, sizeof(dp));
for(i=0;i<n;i++){
for(j=T;j>=t[i];j--){
Node temp;
temp.num = dp[j - t[i]].num + 1;
temp.time = dp[j - t[i]].time + t[i];
if(dp[j] < temp) dp[j] = temp;
}
}
cout << "Case " << Case << ": " << dp[T].num+1 << ' ' << dp[T].time+678 << endl;
}
return 0;

#include <iostream>
#include <bits/stdc++.h>

using namespace std;
const int maxn = 100000+10;
int dp[maxn];
int v[maxn];
int cnt[maxn];
int main()
{
int t;
cin >> t;
int kase = 0;
while(t--)
{
int n,w;
cin >> n >> w;
for(int i = 1 ; i <= n ; i ++)
cin >> v[i];
printf("Case %d:",++kase);
memset(dp,0,sizeof(dp));
memset(cnt,0,sizeof(cnt));
for(int i = 1 ; i <= n ; i++)
{
for(int j = w-1 ; j >= v[i] ; j--)
{
if(cnt[j] < cnt[j - v[i]]+1)
{
dp[j] = dp[j-v[i]]+v[i];
cnt[j] = cnt[j-v[i]]+1;
}
else if(cnt[j] == cnt[j-v[i]]+1)
dp[j] = max(dp[j],dp[j-v[i]]+v[i]);
}
}
cout << " " << cnt[w-1]+1 << " " << dp[w-1]+678 << endl;
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 55, M = 180;
int c
, d[N * M], t, n;

int main()
{
int cas, ans;
scanf("%d", &cas);
for(int k = 1; k <= cas; ++k)
{
memset(d, 0x8f, sizeof(d));
scanf("%d%d", &n, &t);
for(int i = 0; i < n; ++i) scanf("%d", &c[i]);
d[0] = 0;
for(int i = 0; i < n; ++i)
for(int j = t - 1; j >= c[i]; --j)
d[j] = max(d[j], d[j - c[i]] + 1);
for(int j = ans = t - 1; j >= 0; --j) if(d[j] > d[ans]) ans = j;
printf("Case %d: %d %d\n", k, d[ans] + 1, ans + 678);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: