zoukankan      html  css  js  c++  java
  • HDU-1171 Big Event in HDU

    Big Event in HDU

    Problem Description
    Nowadays, we all know that Computer College is the biggest department in HDU. But, maybe you don't know that Computer College had ever been split into Computer College and Software College in 2002.
    The splitting is absolutely a big event in HDU! At the same time, it is a trouble thing too. All facilities must go halves. First, all facilities are assessed, and two facilities are thought to be same if they have the same value. It is assumed that there is N (0<N<1000) kinds of facilities (different value, different kinds).
     
    Input
    Input contains multiple test cases. Each test case starts with a number N (0 < N <= 50 -- the total number of different facilities). The next N lines contain an integer V (0<V<=50 --value of facility) and an integer M (0<M<=100 --corresponding number of the facilities) each. You can assume that all V are different.
    A test case starting with a negative integer terminates input and this test case is not to be processed.
     
    Output
    For each case, print one line containing two integers A and B which denote the value of Computer College and Software College will get respectively. A and B should be as equal as possible. At the same time, you should guarantee that A is not less than B.
     
    Sample Input
    2
    10 1
    20 1
    3
    10 1
    20 2
    30 1
    -1
     
    Sample Output
    20 10
    40 40
     
    可能是自己的做题意识还不够,做的时候总是不能是最简思路。
    然后昨天晚上和亮哥说的时候,他教给我一种方法,既然求得是尽可能将物品的价值平分,那就先dp一遍,然后在dp的结果里边找,是否存在能将物品的总价值平分的结果,如果存在这种情况,输出就OK。但是亮哥告诉我的在不能平分的情况下的方法是错的,好吧,我又去参考博客了。
    因为要得到尽可能平分的情况,在认为物品的价值与物品占用空间相同的情况下,在dp过后哦,在总空间 二分之一 的大小时,dp[half]就是尽可能平分的情况。因为尽可能将一半填满嘛。
    ///先进行一遍dp过程,因为反正都要进行判断是否能够均分,
    ///dp过程不能在中间过程断开,要进行完才行
    
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    const int max_1 = 100000 + 100;
    const int max_2 = 100;
    int val[max_2];
    int num[max_2];
    int dp[max_1];
    
    int main()
    {
        int n, ans;
    
        while(~scanf("%d", &n))
        {
            if(n <= 0)
                break;
            memset(dp, 0, sizeof(dp));
            ans = 0;
            for(int i = 0; i < n; i++)
            {
                scanf("%d %d", val+i, num+i);///物品所占的体积与其的价值等值
                ans += val[i] * num[i];
            }
    
            for(int i = 0; i < n; i++)
            {
                int k = 1;
                while(k < num[i])
                {
                    for(int j = max_1; j - val[i]*k >= 0; j--)
                        dp[j] = max(dp[j], dp[j - k*val[i]] + k*val[i]);
                    num[i] -= k;
                    k *= 2;
                }
    
                for(int j = max_1; j - val[i]*num[i] >= 0; j--)
                {
                    dp[j] = max(dp[j], dp[j-val[i]*num[i]] + num[i]*val[i]);
                }
            }
    
    //        printf("%d
    ", dp[max_1]);
            int half = ans / 2;
    
            if(dp[half] < ans - dp[half])
            {
                printf("%d %d
    ", ans - dp[half], dp[half]);
            }
            else
            {
                printf("%d %d
    ", dp[half],ans - dp[half]);
            }
        }
        return 0;
    }
    View Code

    参考:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 
     5 using namespace std;
     6 const int max_1 = 100000 + 10;
     7 const int max_2 = 101;
     8 int val[max_2];
     9 int num[max_2];
    10 int dp[max_1];
    11 
    12 int main()
    13 {
    14     int n;
    15     int ans, half;
    16     while(~scanf("%d", &n))
    17     {
    18         if(n <= 0)
    19             break;
    20 
    21         ans = 0;
    22         memset(dp, 0, sizeof(dp));
    23         for(int i = 0; i < n; i++)
    24         {
    25             scanf("%d %d", val+i, num+i);
    26             ans += val[i] * num[i];
    27         }
    28 
    29         half = ans / 2;
    30         for(int i = 0; i < n; i++)
    31         {
    32             if(val[i] * num[i] >= half)
    33             {
    34                 for(int j = val[i]; j <= half; j++)
    35                 {
    36                     dp[j] = max(dp[j], dp[j - val[i]] + val[i]);
    37                 }
    38                 //printf("%d
    ", dp[half]);
    39             }
    40             else
    41             {
    42                 int k = 1;
    43                 while(k < num[i])
    44                 {
    45                     for(int j = half; j - k*val[i] >= 0; j--)
    46                     {
    47                         dp[j] = max(dp[j], dp[j - k*val[i]] + k*val[i]);
    48                     }
    49                     num[i] -= k;
    50                     k *= 2;
    51                 }
    52 
    53                 for(int j = half; j - num[i]*val[i] >= 0; j--)
    54                 {
    55                     dp[j] = max(dp[j], dp[j - num[i]*val[i]] + num[i]*val[i]);
    56                 }
    57             }
    58 
    59         }
    60 
    61         if(dp[half] < ans - dp[half])
    62         {
    63             printf("%d %d
    ", ans - dp[half], dp[half]);
    64         }
    65         else
    66         {
    67             printf("%d %d
    ", dp[half],ans - dp[half]);
    68         }
    69     }
    70     return 0;
    71 }
    View Code
  • 相关阅读:
    ADO连接access和oracle的一个区别
    我的大救星——Oracle APEX 快速Web开发(鼠标点点即可开发出专业级Web应用)
    Sql Server 2008 R2 error:40 错误处理
    我的第一个WPF程序
    开源社会网络分析工具NodeXL介绍
    JavaScript学习笔记1之基础知识点
    JavaScript学习笔记6 之经典神坑题整理
    JavaScript学习笔记2之Tab切换
    变量声明和函数声明会提升到当前作用域顶部
    JavaScript学习笔记5 之 计时器 & scroll、offset、client系列属性 & 图片无缝滚动
  • 原文地址:https://www.cnblogs.com/ya-cpp/p/4344697.html
Copyright © 2011-2022 走看看