您的位置:首页 > 其它

POJ 2184 Cow Exhibition(背包)

2015-10-17 13:18 453 查看
希望Total Smart和Totol Funess都尽量大,两者之间的关系是鱼和熊掌。这种矛盾和背包的容量和价值相似。

dp[第i只牛][j = 当前TotS] = 最大的TotF。

dp[i][j] = max(dp[i-1][j-s[i]])。

滚动数组根据j-s[i]和j大小关系决定递推顺序。

中间的j或者TF都可以为负,把j都加上下界的绝对值bound变成正数,最后再减掉就好。

对于s[i]和f[i]取值特殊的可以直接贪心

(1e8跑起来并不虚

#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<queue>
#include<vector>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
//#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e3+5, maxs = 2e5, bound = 1e5;
int s[maxn], f[maxn];
int dp[maxs+5];

//#define LOCAL
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif
int n, c = 0; cin>>n;
int TS = 0, TF = 0;
for(int i = n; i--;){
scanf("%d%d",s+c,f+c);
if(s[c]>0 && f[c]>0){
TS += s[c];
TF += f[c];
continue;
}
if(s[c]<= 0 && f[c] <=0) continue;
c++;
}
memset(dp,0xc0,sizeof(dp));
dp[bound] = 0;
for(int i = c; i--;){
if(s[i]>0){
for(int j = maxs; j >= s[i]; j--){
dp[j] = max(dp[j],dp[j-s[i]] + f[i]);
}
}
else {
for(int j = 0; j-s[i] <= maxs; j++){
dp[j] = max(dp[j],dp[j-s[i]] + f[i]);
}
}
}
int ans = bound;
for(int i = bound; i <= maxs; i++){
if(dp[i]+TF>=0) ans = max(i+dp[i],ans);
}
printf("%d\n",ans-bound+TS+TF);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: