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

你可能感兴趣的:(cpp)