5月1日

poj2184

题意:给定奶牛的一些智慧跟幽默值,求在智慧跟幽默值都大于0时,智慧跟幽默的最大值

分析:这题要好好总结一下,看了题解才做出来的。一道很经典的01背包变种题。这里我们将智慧看成容量,幽默看成价值,当智慧为正数时,因为我们后面的状态是由前面的状态来定义的,所以我们采用从大到小逆推,就是普通的01背包,而当智慧为负值时,同样后面的状态也是由前面来确定的,故应该从小到大顺推。另外我们用0到9999表示智慧为负值,100001到200000表示智慧为正值,最后只需在智慧正值的区间中查找。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <string>
 5 #include <vector>
 6 #include <algorithm>
 7 #include <set>
 8 #include <map>
 9 #include <bitset>
10 #include <cmath>
11 #include <queue>
12 #include <stack>
13 using namespace std;
14 const int maxn=110;
15 const int maxm=200001;
16 const int inf=1<<30;
17 int s[maxn],f[maxn];
18 int n;
19 int dp[maxm];
20 int main()
21 {
22     while(cin>>n)
23     {
24         for(int i=0;i<n;i++)
25             cin>>s[i]>>f[i];
26         for(int i=0;i<=maxm-1;i++)
27             dp[i]=-inf;
28         dp[100000]=0; //作为智力正负的分界线
29         for(int i=0;i<n;i++)
30         {
31             if(s[i]<0&&f[i]<0) continue; 
32             if(s[i]>0)  //考虑智力大于0的情况
33             {
34                 for(int j=maxm-1;j>=s[i];j--)
35                 {
36                     if(dp[j-s[i]]>-inf)
37                         dp[j]=max(dp[j],dp[j-s[i]]+f[i]);
38                 }
39             }else{      //考虑智力小于0的情况
40                 for(int j=s[i];j<maxm-1+s[i];j++){
41                     if(dp[j-s[i]]>-inf)
42                         dp[j]=max(dp[j],dp[j-s[i]]+f[i]);
43                 }
44             }
45         }
46         int ans=-inf;
47         for(int i=100000;i<=maxm-1;i++){
48             if(dp[i]>=0)
49                 ans=max(ans,dp[i]+i-100000);
50         }
51         cout<<ans<<endl;
52     }
53     return 0;
54 }
View Code

感觉下一步要去刷一波做奶牛题了,2333

posted @ 2016-05-02 00:13  wolf940509  阅读(153)  评论(0编辑  收藏  举报