poj 2184 Cow Exhibition

来源:互联网 发布:剑三捏脸数据萝莉万花 编辑:程序博客网 时间:2024/04/29 09:47

本人推荐的好题,以前写了一题是balance,然后脑筋不行,直接来了个3维的,写到一半直接放弃了。去网上学习了下,这题完全可以转换为2维的,只需要初始化的时将所有的值都编程负无穷。

题意:给你n头牛,每头牛都有对应的智商和情商,让你选择一些牛,使得最后情商与智商的和最大(并且2者分别之和都为非负)。

思路:肯定是01背包,但是这个维数的转换是必须的,还应注意到这里面的值有正负2种,负的需要从小到大,正的大到小就ok,这里需要用到一个优化,一直记录现在的2个端点值。然后2维遍历的时候只需要遍历这个范围就行了。(有负值,则需要弄个转换点,使其全为正的)。

状态转移方程:dp[j+to] = max(dp[j+to],dp[j+to-arr1[i]]+arr2[i]);


#include<cstdio>#include<cstring>#include<iostream>#define N 101#define to 100000#define MAXN 200001#define INF 0x3f3f3f3f#define max(a1,b1) (a1)>(b1)?(a1):(b1)#define min(a1,b1) (a1)>(b1)?(b1):(a1)using namespace std;int arr1[N],arr2[N],n,dp[MAXN];void solve(){  for(int i=0;i<MAXN;++i)    dp[i] = -INF;  dp[to] = 0;  int l = 0,r = 0;  for(int i=1;i<=n;++i)  {      l = min(l,arr1[i]+l);      r = max(r,arr1[i]+r);      if(arr1[i]>0)      {        for(int j=r;j>=l;--j)      {        dp[j+to] = max(dp[j+to],dp[j+to-arr1[i]]+arr2[i]);      }      }      else      {          for(int j=l;j<=r;++j)          dp[j+to] = max(dp[j+to],dp[j+to-arr1[i]]+arr2[i]);      }  }  int ans = 0;  for(int i=0;i<=r;++i)    if(dp[i+to]>=0)    ans = max(ans,dp[i+to]+i);  cout<<ans<<endl;}int main(void){    while(cin>>n)    {    for(int i=1;i<=n;++i)    {    scanf("%d %d",arr1+i,arr2+i);    }    solve();    }    return 0;}


原创粉丝点击