POJ 2184 Cow Exhibition (變種01背包),poj2184
題意:有一些奶牛,他們有一定的s值和f值,這些值有正有負,最後讓保證s的和為非負且f的和為非負的情況下,s+f的最大值。
思路:很明顯的就是取與不取的問題,對於這類問題的第一想法就是背包,但是這道題目很明顯與一般的背包不同,因為有負數,但是聯想到以前也有這種將負數存入下標的情況,那就是將數組開大,換一種存法
我們用dp[i]存放每個s[i]能得到的最佳F,那麼我們就可以根據s[i]的取值採取兩種不同的01背包取法,在取完之後,然後再根據背包的有無再去求得最佳答案即可
#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;int dp[200005];const int inf = 1<<30;int main(){ int n,s[200],f[200],i,j,ans; while(~scanf("%d",&n)) { for(i = 0; i<=200000; i++) dp[i] = -inf; dp[100000] = 0; for(i = 1; i<=n; i++) scanf("%d%d",&s[i],&f[i]); for(i = 1; i<=n; i++) { if(s[i]<0 && f[i]<0) continue; if(s[i]>0) { for(j = 200000; j>=s[i]; j--)//如果s[i]為整數,那麼我們就從大的往小的方向進行背包 if(dp[j-s[i]]>-inf) dp[j] = max(dp[j],dp[j-s[i]]+f[i]); } else { for(j = s[i]; j<=200000+s[i]; j++)//為負數則需要反過來 if(dp[j-s[i]]>-inf) dp[j] = max(dp[j],dp[j-s[i]]+f[i]); } } ans = -inf; for(i = 100000; i<=200000; i++) { if(dp[i]>=0) ans = max(ans,dp[i]+i-100000); } printf("%d\n",ans); } return 0;}