题意
现在,有一个 n ∗ n n * n n∗n的网格图,左下角坐标是 ( 1 , 1 ) (1, 1) (1,1),右上角坐标是 ( n , n ) (n, n) (n,n)。有一个小 S B SB SB正在坐标为 ( n , 1 ) (n, 1) (n,1)的位置,每一时刻,如果他现在在 ( x , y ) (x, y) (x,y),他可以选择走到 ( x − 1 , y + 1 ) (x -1,y + 1) (x−1,y+1) 或者 ( x , ( y + 1 ) d i v 2 ) (x, (y + 1)\ div\ 2) (x,(y+1) div 2),如果选择后者,他要支付 B x B_x Bx的代价。
其中 B B B为数组 A A A的后缀和。
思路
首先可以想到动态规划,乱搞一下 O ( N 2 ) O(N^2) O(N2),只有50分。
然后看一下题解发现是合并果子,直接怒切。
有待研究~
代码
#pragma GCC optimize(2)
#include<queue>
#include<cstdio>std::priority_queue<int> q;
int t, n;
long long ans;long long input() {char c = getchar();int f = 1;long long result = 0;while (c < '0' || c > '9') {if (c == '-') f = -1;c = getchar();}while (c >= '0' && c <= '9') {result = result * 10 + (c - 48);c = getchar();}return result * f;
}void print(long long x) {if (x > 9) print(x / 10);putchar(x % 10 + 48);
}int main() {t = input();for (; t; t--) {n = input();ans = 0;int x, y;for (int i = 1; i <= n; i++) {x = input();q.push(-x);}while ((int)q.size() >= 2) {x = -q.top();q.pop();y = -q.top();q.pop();ans += x + y;q.push(-x - y);}q.pop();print(ans);putchar(10);}
}