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;
}

posted @ 2019-08-16 15:25  KirinSB  阅读(153)  评论(0编辑  收藏  举报