zoukankan      html  css  js  c++  java
  • POJ2184——背包DP——Cow Exhibition

    Description

    "Fat and docile, big and dumb, they look so stupid, they aren't much 
    fun..." 
    - Cows with Guns by Dana Lyons 

    The cows want to prove to the public that they are both smart and fun. In order to do this, Bessie has organized an exhibition that will be put on by the cows. She has given each of the N (1 <= N <= 100) cows a thorough interview and determined two values for each cow: the smartness Si (-1000 <= Si <= 1000) of the cow and the funness Fi (-1000 <= Fi <= 1000) of the cow. 

    Bessie must choose which cows she wants to bring to her exhibition. She believes that the total smartness TS of the group is the sum of the Si's and, likewise, the total funness TF of the group is the sum of the Fi's. Bessie wants to maximize the sum of TS and TF, but she also wants both of these values to be non-negative (since she must also show that the cows are well-rounded; a negative TS or TF would ruin this). Help Bessie maximize the sum of TS and TF without letting either of these values become negative. 

    Input

    * Line 1: A single integer N, the number of cows 

    * Lines 2..N+1: Two space-separated integers Si and Fi, respectively the smartness and funness for each cow. 

    Output

    * Line 1: One integer: the optimal sum of TS and TF such that both TS and TF are non-negative. If no subset of the cows has non-negative TS and non- negative TF, print 0. 

    Sample Input

    5
    -5 7
    8 -6
    6 -3
    2 1
    -8 -5
    

    Sample Output

    8
    

    Hint

    OUTPUT DETAILS: 

    Bessie chooses cows 1, 3, and 4, giving values of TS = -5+6+2 = 3 and TF 
    = 7-3+1 = 5, so 3+5 = 8. Note that adding cow 2 would improve the value 
    of TS+TF to 10, but the new value of TF would be negative, so it is not 
    allowed. 
     大意:有两组数据,求将两组数据分别相加之后和的最大值(必须满足这两组数据的和都为正)
    将a[i]看作是花费,b[i]看作是价值,因为存在负值,所以进行讨论,如果a[i]大于0就相当于普通的01背包,如果a[i]小于0,则是01背包的逆(填充空间却有价值,就是要算填充空间最少时价值的最大,而01背包是消耗空间最小时价值的最大)只要将for循环倒过来,01背包完全背包for的循环条件都是在(0...V),所以(a[i],a[i]+200000)(与完全背包区分,完全背包是(0..V)因为要下表不为负所以写成(a[i]...V)),所以每一个dp[i]为以a[i]为下标的最大的价值,最后只要遍历,找到dp[i]+i-100000就是(if(dp)和i从100000遍历保证不出现sum为负的情况)比较难想,负数处理只要给定中间值,背包大小100000 = 100*1000。
    (why?01背包完全背包for条件必须在(0,V)区间里面)
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int inf = 0x3f3f3f3f;
    const int MAX = 100000+5;
    int dp[2*MAX];
    int a[105],b[105];
    int main()
    {
        int x,y;
        int T;
        while(~scanf("%d",&T)){
            memset(a,0,sizeof(a));
            memset(b,0,sizeof(b));
            for(int i = 1 ; i <= T; i++){
                scanf("%d%d",&a[i],&b[i]);
            }
            for(int i = 0; i <= 200000;i++)
                dp[i] = -inf;
            dp[100000] = 0;
            for(int i = 1; i <= T; i++){
                if(a[i] < 0 && b[i] < 0)
                    continue;
                else if(a[i] > 0){
                    for(int j = 200000; j >= a[i]; j--){
                         if(dp[j-a[i]] > - inf){
                      dp[j] = max(dp[j],dp[j-a[i]] + b[i]);
                         }
                    }
                }
                else {
                    for(int j = a[i]; j <= 200000+a[i]; j++){
                        if(dp[j-a[i]] > -inf){
                        dp[j] = max(dp[j],dp[j-a[i]]+b[i]);
                        }
                    }
                }        
            }
            int max1 = -inf;
            for(int i = 100000; i <= 200000; i++){
                if(dp[i] >= 0)
                max1 = max(max1,dp[i]+i-100000);
                    }
                    printf("%d
    ",max1);
                }
            return 0;
    }
    View Code
  • 相关阅读:
    linux截图工具
    Git理论知识补充
    Git基本操作(add,commit的理解)
    VS2017 error CS0234: 命名空间“Microsoft”中不存在类型或命名空间名“Office”问题的一种解决方案
    MFC CFileDialog DoModal()无法弹出窗口,直接返回IDCANCEL
    VS2015 、VS2017 MFC输出日志到控制台窗口
    win10 VMware 关闭虚拟机失败导致再打开时显示连接不上虚拟机的一种解决方法
    c语言之位段
    Adobe Acrobat DC 制作多级书签
    MFC基于对画框工程笔记->更改窗口图标以及生成的.exe图标
  • 原文地址:https://www.cnblogs.com/zero-begin/p/4447966.html
Copyright © 2011-2022 走看看