zoukankan      html  css  js  c++  java
  • 01背包(体积为负,改变区间) 之 poj 2184

    //  [7/21/2014 Sjm]
    /*
    题意:maximize the sum of TS and TF, but both of these values to be non-negative.
     
    解决思路:
    以 TS 作为体积,TF作为价值,在保证体积、价值非负的情况下,求解 sum,取其所有情况的最大值。
     
    难点:
    1)体积出现负数,将区间改变 [-100000, 100000] ---> [0, 200000]。
    	(注意此时始点 dp[100000], [0, 100000)表示 TS 为负,(100000, 200000]表示 TS 为正)
    2)状态转移时,对于 smartness 出现负数的处理
    	(二维更好理解一些,但是若写成一维,则注意内层循环的循环顺序(思想同“背包九讲”里的“优化空间”的方法))
    (在我看来:关键是对状态转移方程的理解程度,知道所求值是依赖谁求出来的,在一维数组中各个值的位置又在哪里)
    3)千万注意初始化,因为要保证“必须把背包装满”。。。
     1 #include <iostream>
     2 #include <cstdlib>
     3 #include <cstdio>
     4 #include <algorithm>
     5 #include <cstring>
     6 using namespace std;
     7 const int MAX = 200005;
     8 const int INF = 0x3f3f3f3f;
     9 int arr[105][2], dp[MAX];
    10 int sum, N;
    11 
    12 int Solve() {
    13     memset(dp, -INF, sizeof(dp));
    14     dp[100000] = 0;
    15     for (int i = 1; i <= N; ++i) {
    16         if (arr[i][0] > 0) {
    17             for (int j = sum; j >= arr[i][0]; --j) {  // 注意循环顺序,从大到小
    18                 if (dp[j - arr[i][0]] > -INF) {
    19                     dp[j] = max(dp[j], dp[j - arr[i][0]] + arr[i][1]);
    20                 }
    21             }
    22         }
    23         else {
    24             for (int j = 0; j <= sum + arr[i][0]; ++j) { // 注意循环次序,从小到大
    25                 if (dp[j - arr[i][0]] > -INF) {
    26                     dp[j] = max(dp[j], dp[j - arr[i][0]] + arr[i][1]);
    27                 }
    28             }
    29         }
    30     }
    31     int ans = 0;
    32     // 由 TS 非负值的计算结果
    33     for (int i = sum; i >= 100000; --i) {
    34         if (dp[i] >= 0) {  // 保证 TF 非负
    35             ans = max(ans, dp[i] + i - 100000);
    36         }
    37     }
    38     return ans;
    39 }
    40 
    41 int main()
    42 {
    43     //freopen("input.txt", "r", stdin);
    44     scanf("%d", &N);
    45     int sum1 = 0, sum2 = 0;
    46     for (int i = 1; i <= N; ++i) {
    47         scanf("%d %d", &arr[i][0], &arr[i][1]);
    48         if (arr[i][0] > 0) {
    49             sum += arr[i][0];
    50         }
    51     }
    52     sum = sum + 100000;  // TS 上界
    53     printf("%d
    ", Solve());
    54     return 0;
    55 }
  • 相关阅读:
    scala学习笔记(8)
    mysql复习(1)基本CRUD操作
    sql获得表主键信息
    C#缓存-依赖 CacheHelper
    MVC过滤器实现用户登录验证
    MVC过滤器
    MVC页面和表单
    在ASP.NET中基于Owin OAuth使用Client Credentials Grant授权发放Token
    MVC DbContext
    MVC数据注解
  • 原文地址:https://www.cnblogs.com/shijianming/p/4140825.html
Copyright © 2011-2022 走看看