zoukankan      html  css  js  c++  java
  • EOJ2927 负载平衡问题

    链接: http://www.acm.cs.ecnu.edu.cn/problem.php?problemid=2927

        这道题用了均分纸牌的方法
        开始容易想到在所有的仓库中找到最多的库存量,然后向小的仓库移动,一直到所有的货物都相等,但关键是不知道往哪个方向上移动才能达到移动次数最少。设a[i]为第i个仓库的库存量(0<=i<=n),ave为均分后每个仓库的库存量,ans为最小移到次数。我们按照由左而右的顺序移动货物。若第i个仓库的库存量a[i]超出平均值,则移动一次(ans+1),将超出部分留给下一个仓库,既第i+1个仓库的库存量增加a[i]-ave;若第i个仓库的库存量a[i]少于平均值,则移动一次(ans+1),由下一个补充不足部分,既第i+1个仓库的库存量减少ave-a[i];
        问题是,在从第i+1个仓库中取出货物补充第i个仓库的过程中,可能会出现第i+1个仓库的货物数小于零(a[i+1]-(ave-a[i])<0)的情况,但由于货物的总数是n的倍数,因此后面的仓库会补充第i+1个仓库ave-a[i]-a[i+1]+ ave个货物,使其达到均分的要求。我们在移动过程中,只是改变了移动的顺序,而移动的次数不变,因此此题使用该方法是可行的。
        例如:1  2  27
        我们从第三堆移出8个到第二堆后,第二堆有10个货物,第三堆剩下19张货物,再从第三堆移动9个到第一堆,刚好三堆货物数都是10,最后结果是对的,一共需要17次移动
        此题的原理是贪心,每次使左边的货物达到平均值,最终由n个不同的开始有n种不同的答案,遍历一遍取最小值即为所求值。

     1 #include <iostream>
     2 #include <cmath>
     3 using namespace std;
     4  
     5 int n, a[105], ans, ave;
     6  
     7 int main()
     8 {
     9     while (cin >> n)
    10     {
    11         int s = 0;
    12         ans = 99999;
    13         for (int i = 0; i < n; i++)
    14         {
    15             cin >> a[i];
    16             s += a[i];
    17         }
    18         ave = s/n;
    19         for (int i = 0; i < n; i++)
    20             a[i] -= ave;
    21         for (int i = 0; i < n; i++)
    22         {
    23             int t = 0, x = 0;
    24             for (int j = 0; j < n - 1; j++)
    25             {
    26                 t += a[(j + i)%n];
    27                 x += abs(t);
    28             }
    29             ans = min(x, ans);
    30         }
    31         cout << ans << endl;
    32     }
    33     return 0;
    34 }
    View Code
  • 相关阅读:
    SpringMvc完成ajax功能
    接收的参数为日期类型
    Mybatis的逆向工程(generator)以及分页助手(pageHelper)
    springMVC静态资源的映射
    Mybatis框架
    写一个简单的SpringMvc的demo
    SpringMvc流程
    controller进行数据保存以及如何进行重定向跳转
    我爱C语言
    三列布局中有两列内容固定
  • 原文地址:https://www.cnblogs.com/KimKyeYu/p/3128685.html
Copyright © 2011-2022 走看看