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
  • 相关阅读:
    java实现微信红包分配算法
    认识J2SE
    java设计模式(2)
    java设计模式(1)
    模拟做饭系统(java+线程中的join方法)
    学习接水系统(java+thread线程)
    1. linux系统简介
    Codeforces Round #350 (Div. 2)解题报告
    2014蓝桥杯决赛解题报告
    末学者笔记--Python函数一玄
  • 原文地址:https://www.cnblogs.com/ya-cpp/p/4344697.html
Copyright © 2011-2022 走看看