POJ 1738 An old Stone Game(GarsiaWachs)题解
题意:
石子合并,问最小代价
思路:
GarsiaWachs,朴素做法\(O(n^2)\)复杂度,实际上比这个稍微小点。平衡树优化能到\(O(nlogn)\)。
代码:
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<ctime>
#include<cmath>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 5e4 + 5;
const int INF = 0x3f3f3f3f;
const ull seed = 131;
const ll MOD = 1e9 + 7;
using namespace std;
int stone[maxn], ans, now;
void combine(int k){
int tmp = stone[k] + stone[k - 1];
ans += tmp;
for(int i = k; i < now - 1; i++)
stone[i] = stone[i + 1];
now--;
int j = 0;
for(j = k - 1; j > 0 && stone[j - 1] < tmp; j--)
stone[j] = stone[j - 1];
stone[j] = tmp;
while(j >= 2 && stone[j] >= stone[j - 2]){
int d = now - j;
combine(j - 1);
j = now - d;
}
}
int main(){
int n;
while(~scanf("%d", &n) && n){
for(int i = 0; i < n; i++){
scanf("%d", &stone[i]);
}
ans = 0;
now = 1;
for(int i = 1; i < n; i++){
stone[now++] = stone[i];
while(now >= 3 && stone[now - 3] <= stone[now - 1]){
combine(now - 2);
}
}
while(now > 1) combine(now - 1);
printf("%d\n", ans);
}
return 0;
}