Codeforces Round #186 (Div. 2) C. Ilya and Matrix

题目链接:http://codeforces.com/problemset/problem/313/C

题目大意:

  还是看原题吧,意思不难懂。

题目思路:

  开始一直没有想法,后来听一然酱讲了才好不容易搞懂,赶脚好神奇。

  构造的思路应该算贪心,先把前4大的数字排列到最先划分的4个方格里面,然后再依次把后面比较大的数字依次填充到这四个方格里空着的小格子里面,直到所有的格子填满为止,为什么这个思路是正确的呢?还是模拟一下4*4的格子就差不多理解了吧。

  但是关键是怎么算出递归得到的结果?一然酱的思路很巧妙,先把数字逆序排列,再把前序和算出来,目的是方便后面的求和,然后从递归的最底层开始考虑。最底层肯定是所有的数字都包括,也就是前N个数字的和,再往上走,就是前N/4个数字的和,直到N<1为止。碉堡了……

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <cstring>
 6 using namespace std;
 7 #define LL long long int
 8 const int MAX = 1000000*2+10;
 9 LL a[MAX], ans, n;
10 bool cmp2(LL a, LL b) {
11   return a > b;
12 }
13 int main(void) {
14   while (~scanf("%I64d", &n)) {
15     int i;
16     for (i = 0; i < n; ++i) scanf("%I64d", a+i);
17     sort(a, a+n, cmp2);
18     for (i = 1; i < n; ++i) a[i] += a[i-1];
19     ans = 0;
20     while (n >= 1) {
21       ans += a[n-1];
22       n = n >> 2;
23     }
24     printf("%I64d\n", ans);
25   }
26   return 0 ;
27 }

然后就是注意一下类型用LL……

这回跟一然酱去网吧做CF,感触颇深,看人家神牛怎么做比赛的,给跪……谢谢一然酱~

原文地址:https://www.cnblogs.com/liuxueyang/p/3109988.html