• hdoj1171 Big Event in HDU(01背包 || 多重背包)


    题目链接

    http://acm.hdu.edu.cn/showproblem.php?pid=1171

    题意

    老师有一个属性:价值(value)。在学院里的老师共有n种价值,每一种价值value对应着m个老师,说明这m个老师的价值都为value。现在要将这些老师从人数上平分成两个院系,并且希望平分后两个院系老师的总价值A和B应尽可能地相等,求A和B的值(A>=B)。

    思路

    由于每种老师的个数是有限的,所以使用多重背包解决。由于测试数据不是很严格,所以使用01背包也可以通过。

    代码

    01背包:

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <cstdio>
     5 using namespace std;
     6 
     7 const int N = 5010;
     8 const int M = 50 * 5000;
     9 int v[N];
    10 int dp[M];
    11 
    12 int main()
    13 {
    14     //freopen("hdoj1171.txt", "r", stdin);
    15     int n;
    16     while (cin >> n && n >= 0)
    17     {
    18         int cur = 0;    //记录教师总数
    19         int sum = 0;    //记录教师总价值
    20         for (int i = 0;i < n; i++)
    21         {
    22             int val, m;
    23             cin >> val >> m;
    24             for (int j = 0; j < m; j++)
    25             {
    26                 v[cur++] = val;
    27                 sum += val;
    28             }
    29         }
    30 
    31         memset(dp, 0, sizeof(dp));
    32         for (int i = 0; i < cur; i++)
    33         {
    34             for (int j = sum / 2; j >= v[i]; j--)
    35                 dp[j] = max(dp[j], dp[j - v[i]] + v[i]);    //weight和value相同
    36         }
    37         //由于dp[sum/2]<sum/2,所以dp[sum/2]一定是较小者,sum - dp[sum / 2]是较大者
    38         cout << sum - dp[sum / 2] << " " << dp[sum / 2] << endl;
    39     }
    40     return 0;
    41 

    多重背包:

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <cstdio>
     5 using namespace std;
     6 
     7 const int N = 110;
     8 const int M = 50 * 5000;
     9 int v[N], num[N];
    10 int dp[M];
    11 int sum;
    12 
    13 void zero_one_pack(int weight, int value, int capacity)
    14 {
    15     for (int i = capacity; i >= weight; i--)    //逆序
    16         dp[i] = max(dp[i], dp[i - weight] + value);
    17 }
    18 
    19 void complete_pack(int weight, int value, int capacity)
    20 {
    21     for (int i = weight; i <= capacity; i++)    //正序
    22         dp[i] = max(dp[i], dp[i - weight] + value);
    23 }
    24 
    25 void mutiple_pack(int weight, int value, int amount, int capacity)
    26 {
    27     if (weight*amount >= capacity)
    28         complete_pack(weight, value, capacity);
    29     else
    30     {
    31         int k = 1;
    32         while (k <= amount)
    33         {
    34             zero_one_pack(weight*k, value*k, capacity);
    35             amount -= k;
    36             k *= 2;
    37         }
    38         zero_one_pack(weight*amount, value*amount, capacity);
    39     }
    40 
    41 }
    42 
    43 int main()
    44 {
    45     //freopen("hdoj1171.txt", "r", stdin);
    46     int n;
    47     while (cin >> n && n >= 0)
    48     {
    49         sum = 0;
    50         for (int i = 1; i <= n; i++)
    51         {
    52             cin >> v[i] >> num[i];
    53             sum += v[i] * num[i];
    54         }
    55 
    56         memset(dp, 0, sizeof(dp));
    57         for (int i = 1; i <= n; i++)
    58             mutiple_pack(v[i], v[i], num[i], sum / 2);
    59 
    60         cout << sum - dp[sum / 2] << " " << dp[sum / 2] << endl;
    61     }
    62 }
  • 相关阅读:
    118/119. Pascal's Triangle/II
    160. Intersection of Two Linked Lists
    168. Excel Sheet Column Title
    167. Two Sum II
    172. Factorial Trailing Zeroes
    169. Majority Element
    189. Rotate Array
    202. Happy Number
    204. Count Primes
    MVC之Model元数据
  • 原文地址:https://www.cnblogs.com/sench/p/8013013.html
Copyright © 2020-2023  润新知