您的位置:首页 > 其它

poj Cow Exhibition 01背包的灵活运用

2011-08-16 19:06 253 查看
这道题起初我看是一点思路都没有,后来瞄一眼解题报告才知是另一背包,可还是做不出来,又把结题报告看一遍,才理解,废话不多说了。。。。

这道题主要是有了两个变量,但我们可以先锁定一个变量si,因为有负数,所以将si的范围锁定到1到200000,理由01背包计算出每一个si值所对应的最大值dp【i】,也就是fi,还值得注意的是,01背包的时候si有正有负,当si为正的时候我们就从大往小搜,而si为负是从小往大搜,因为01背包是每个物品只用一次的,而当si为负的时候,恰恰需要我们从小往大搜,保证每个si只用一次,这也是01背包和完全背包的重要区别,大家要注意啊!!!!!!

#include<iostream>

using namespace std;

int si[105],fi[105];

#define N 200005

int max(int x,int y)

{

return x>y? x:y;

}

int dp
;

int main()

{

int n;

while(cin>>n)

{

int inf=-0x7FFFFFFF;//值得注意一开始我就开小了!!!!

for(int i=0;i<=200000;i++)

dp[i]=inf;

dp[100000]=0;// 背包时要有初始值,否则背包进行比较将没有起点

for(int i=1;i<=n;i++)

scanf("%d%d",&si[i],&fi[i]);

for(int i=1;i<=n;i++)

{

if(si[i]<0&&fi[i]<0)//注意一下,我已开始忘打了

continue;

if(si[i]>0)

{

for(int j=200000;j>=si[i];j--)//0-1背包了,注意从大到小

if(dp[j-si[i]]>inf)

dp[j]=max(dp[j-si[i]]+fi[i],dp[j]);

}

else

{

for(int j=si[i];j<=200000+si[i];j++)//0-1背包,从小到大

if(dp[j-si[i]]>inf)

dp[j]=max(dp[j-si[i]]+fi[i],dp[j]);

}

}

int ans=inf;

for(int i=100000;i<=200000;i++)

{

if(dp[i]>=0)//这个一定要大于等于,因为fi可以为零

ans=max(ans,dp[i]+i-100000);

}

cout<<ans<<endl;

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: