• cf 226b 唯美思维题~.cpp


    题意:

      给出n个数,让你用最少次数把所有的数都摞成一堆。

      其中当把arr[i]摞在第j堆上时,得扣分arr[i]

      题目有要求每个数上面不许摞超过k次,有m个k,让你求出m种情况下限制为k时的最优解,即最少扣分。

    思路:

      经过多次推算会发现,如果要最后扣分最少,则应该尽量让arr[i]小的摞的次数比较多,而arr[i]大的摞的次数比较少。

      然后还有一个规律是,如果想让扣分最少,那每次应该尽量让值大的堆上摞的次数比较多,本身则尽量少摞。即尽量满足 一次摞足够多的物品。

    Tips:

      如果k = 1,则答案就是arr[1] + (arr[1]+arr[2]) + (arr[1]+arr[2]+arr[3]) + (arr[1] +...+arr[i]) + (arr[1]+...+arr[i]+...+arr[n-1])//因为最后且最大的一摞不用动~所以只需要加到arr[n-1]

      否则答案就是一次摞尽量多的物品,为了令大的物品移动尽量少的次数,我们从倒数第二个到倒数第k+1个开始算,arr[n-1]~arr[n-1-k]只需要移动一次,arr[n-1-k]~arr[n-1-k-k*k]只要移动2次..and so on~~//因为1个上面可以摞k个..所以k个上面可以摞k*k个..所以以倍数的方式递增..

      优化的方法是先计算出从第0个到第i个的和,这样就可以算出其中任意一段的和了。

      所以答案就是while循环算出来的..

    Code:

    View Code
     1 #include <stdio.h>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <ctime>
     5 using namespace std;
     6 
     7 long long sum[100010];
     8 long long arr[100010];
     9 
    10 int main()
    11 {
    12     int n, q, k;
    13     long long ans, tans, tk;
    14     int tmp, tn;
    15     while(EOF != scanf("%d", &n)) {
    16         tans = 0;
    17         for(int i = 1; i <= n; ++i)
    18             scanf("%lld", &arr[i]);
    19         //printf("_\n");
    20         sort(arr+1, arr+n+1);
    21         sum[0] = 0;
    22         for(int i = 1; i <= n; ++i) {
    23             sum[i] = sum[i-1]+arr[i];
    24             if(i != n) tans += sum[i];
    25         }
    26         scanf("%d", &q);
    27         while(q--) {
    28             ans = 0;
    29             tmp = 1;
    30             tn = n-1;
    31             scanf("%d", &k);
    32          //   printf("%d__\n",k);
    33             tk = k;
    34             if(k != 1) {
    35                 while(tn >= tk) {
    36                     ans += (sum[tn]-sum[tn-tk])*tmp;
    37                     tn -= tk;
    38                     tk *= k;
    39                     tmp++;
    40                 }
    41                 ans += (sum[tn]-sum[0])*tmp;
    42             } else ans = tans;
    43             printf("%lld%c", ans, q != 0?' ':'\n');
    44         }
    45     }
    46     return 0;
    47 }

    链接:http://www.codeforces.com/problemset/problem/226/B

  • 相关阅读:
    LINQ篇:ASP.NET using LINQ(Part One) Scott大师的产物
    运算符重载 operator+[纯属温习啊][附加了一些内容 如:同名属性,复制构造函数]
    Vista中低端电脑如何打开Aero效果或者就是3D效果
    基于可配置化的设计[原创][4.20更新]
    Treeview控件如何在asp.net ajax中使用小技巧
    PetShop 4.0 系列之四 [转]
    XML篇查询语言XPath
    抽象工厂模式[转]
    何时使用委托而不使用接口
    DNN开篇第一话
  • 原文地址:https://www.cnblogs.com/Griselda/p/2963912.html
Copyright © 2020-2023  润新知