背包问题!!!
WA。。。。。。。。无语了!!!!(搜索做的,就是过不了)
#include<iostream>
#include<string.h>
#include<queue>
#include<stdio.h>
#include<algorithm>
using namespace std;
queue<int> m;
struct node{int s,f;}a[105];
int sum=0,maxn=0,ts=0,tf=0;
bool com(node x,node y){if(x.s!=y.s) return x.s>y.s;
else
return x.f>y.f;
}
int main(){
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n;
cin>>n;
maxn=0;sum=0;
int k=n;
for(int i=0;i<n;i++) cin>>a[i].s>>a[i].f;
sort(a,a+n,com);
//for(int i=0;i<n;i++) cout<<a[i].s<<endl;
for(int i=0;i<n;i++) if(a[i].s<0&&a[i].f<0){ k=i;break;}
//cout<<k<<endl;
for(int i=0;i<(1<<k);i++)
{
while(!m.empty())m.pop();
sum=0;ts=0;tf=0;
for(int j=0;j<k;j++){
if(i&(1<<j)) m.push(j);
}
int x;
while(!m.empty()){x=m.front();tf+=a[x].f;ts+=a[x].s;sum=sum+a[x].f+a[x].s;m.pop();}
if(ts>=0&&tf>=0)if(sum>maxn) maxn=sum;
}
cout<<maxn<<endl;
system("pause");
return 0;}
------------------------------------------------------------------------------------------------
(0,1)背包的变形,但变得可真厉害,我是开别人的代码好久才弄明白的;
把s看成是背包容量,f看成是价值,
#include<iostream>
#include<string.h>
#define MID 100000
using namespace std;
int vis[200005];//visited[i+MID]标记左边的数能否组成i巧
int dp[200005];//dp[i+MID]总的s值为i时的最优的f值(其实就是说两个都是和的形式)
int main(){
int n;
cin>>n;
memset(vis,0,sizeof(vis));
vis[MID]=1;
int _min=0,_max=0;
for(int i=0;i<200005;i++) dp[i]=-0xffff;
dp[MID]=0;
int s,f;
for(int j=0;j<n;j++){
cin>>s>>f;
if(s<=0&&f<=0) continue;//剪支;只有一个小于或等于0不能被剪
if(s>0){//如果s<0则从小到大,否则从大到小扫描,避免把同一个数加两次。
for(int i=_max;i>=_min;i--){
if(vis[MID+i]) if(dp[MID+i+s]<dp[MID+i]+f)
{dp[MID+i+s]=dp[MID+i]+f;vis[MID+i+s]=1;}
}
_max+=s;
}
else{
for(int i=_min;i<=_max;i++)
if(vis[MID+i]) if(dp[MID+i+s]<dp[MID+i]+f)
{dp[MID+i+s]=dp[MID+i]+f;vis[MID+i+s]=1;
}
_min+=s;
}
}
int rez=0;
for(int i=0;i<=_max;i++)//剪掉了i<0的情况
if(vis[i+MID])
if(dp[i+MID]>=0&&dp[i+MID]+i>rez)
rez=i+dp[i+MID];
cout<<rez<<endl;
return 0;}