Description "Fat and docile, big and dumb, they look so stupid, they aren't much Input * Line 1: A single integer N, the number of cows Output * Line 1: One integer: the optimal sum of TS and TF such that both TS and TF are non-negative. If no subset of the cows has non-negative TS and non- negative TF, print 0. Sample Input 5 -5 7 8 -6 6 -3 2 1 -8 -5 Sample Output 8 Hint OUTPUT DETAILS: |
题目大意:选出一些牛,使smartness和funness值的和最大,而这些牛有些smartness或funness的值是负的,还要求最终的smartness之和以及funness之和不能为负。
分析:这里不就是看哪些牛选,还是不选的问题吗,那么这就是转化为01背包,在这里可以将smartness当做01背包中的体积,funness当做01背包里面的价值,当然你也可以将两者倒过来也是可以的,在代码中我默认市容smartness当做体积;
然后这道题还有一个需要进一步处理的方式就是如何处理,当价值为负数的情况,以前也处理过类似的,方法就是将下标左移扩大,因为所给的数据为[-1000,1000],因此我可以将其变为[0,2000],那么整个背包的体积的使用范围为[0*100,2000*100],那么此时的原点,也就是对称点变为100000,此时dp[100000]=0;其他情况初始化为负无穷,这样在[0,100000]区间里的是原区间[-1000,0],相应的[100000,200000]就是[0,1000];
还有一个地方需要注意的就是当体积为负数的时候与体积为正数的时候的处理情况是不同的;我们在运用一维数组优化01背包的时候说过,推dp的时候是从后往前推,当体积为正数的时候是没有问题,就按照原来的方法套模板,但是当为负数的时候就需要按照正序走一遍dp了(原因);dp[i]是数据中左边一列s的和为s时的最大f值,而s+f=dp[i]+i-10000;
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define lep(i,l,r) for(int i=l;i>=r;i--)
#define ms(arr) memset(arr,0,sizeof(arr))
const int N=2000100;
const int INF=0x3f3f3f3f;
int dp[N];
int a[200],b[200];
int main()
{
// freopen("in.txt","r",stdin);
int n;
scanf("%d",&n);
rep(i,0,200000)
dp[i]=-INF;
dp[100000]=0;
rep(i,1,n){
scanf("%d%d",&a[i],&b[i]);
if(a[i]<=0&&b[i]<=0) i--,n--;
}
rep(i,1,n)
{
if(a[i]>0)
{
for(int j=200000;j>=a[i];j--)
if(dp[j-a[i]]>-INF)//这个和下面的两个if不能去掉,否则会Running Error
dp[j]=max(dp[j],dp[j-a[i]]+b[i]);
}else{
for(int j=a[i];j<=200000+a[i];j++)
if(dp[j-a[i]]>-INF)
dp[j]=max(dp[j],dp[j-a[i]]+b[i]);
}
}
int ans=-INF;
rep(i,100000,200000)
if(dp[i]>=0)
ans=max(ans,dp[i]+i-100000);
printf("%d\n",ans);
return 0;
}
至于为什么上面两个if去掉之后会Running Error,不清楚为什么,望知道的大神能够指出