zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    RHEL7全新初始化进程管理systemd(图形启动和非图形启动切换)
    Linux系统添加硬盘设备(磁盘分区-格式化-挂载-使用)
    linux系统主要常见目录结构
    Linux系统文件访问控制列表
    Linux命令-sudo
    Linux系统文件的隐藏属性
    Linux系统文件权限&目录权限
    Linux系统VIM编辑器
    Linux功能-环境变量
    Linux系统PATH变量配置
  • 原文地址:https://www.cnblogs.com/sench/p/8013013.html
Copyright © 2011-2022 走看看