题意:这是又是一道01背包的变体,题目要求选出一些牛,使smartness和funness值的和最大,而这些牛有些smartness或funness的值是负的,还要求最终的smartness之和以及funness之和不能为负。
自己想不出来,这里值得借鉴的就是把其中一个东西当做费用,另一个当做价值,这样就不用开二维的数组了,
还有就是设置shift来右移i;
照抄自:http://blog.csdn.net/libin56842/article/details/20236597
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<string>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<stack>
#include<cmath>
#include<map>
#include<vector>
#define ll long long
#define bug1 cout<<"bug1"<<endl;
#define bug2 cout<<"bug2"<<endl;
#define bug3 cout<<"bug3"<<endl;
using namespace std;
const int maxn=1005;
const int inf=1<<30;
int s[maxn],f[maxn];
const int maxx=200000;
int dp[maxx];
int mid=100000;
int main(){
int n;
while(~scanf("%d",&n)){
for(int i=1;i<=n;++i){
scanf("%d%d",&s[i],&f[i]);
}
for(int i=0;i<=maxx;++i){
dp[i]=-inf;
}//要注意,自己 的 0x3f3f 貌似不够大, 所以有时候要初始为无穷大的时候要自己写
dp[mid]=0;
for(int i=1;i<=n;++i){
if(s[i]<0&&f[i]<0)continue;
if(s[i]>0){
for(int j=maxx;j>=s[i];j--){
if(dp[j-s[i]]>-inf){//注意这个地方要有,可能是为了减小操作次数的(从250ms到125ms,或者是如果上一层没有结果,那么这一层自然不用计算结果
dp[j]=max(dp[j-s[i]]+f[i],dp[j]);
}
}
}
else{
for(int j=s[i];j<=maxx+s[i];++j){
if(dp[j-s[i]]>-inf)
dp[j]=max(dp[j-s[i]]+f[i],dp[j]);
}
}
}
int ans=0;
for(int i=mid;i<=maxx;++i){
if(dp[i]>=0){
ans=max(ans,dp[i]+i-mid);
}
}
cout<<ans<<'\n';
}
}