石子合并 BZOJ

来源:互联网 发布:小米4s网络制式参数 编辑:程序博客网 时间:2024/05/18 02:35

题目传送门

题意:石子合并问题一般来说都是O(N^3)的复杂度,如果用四边形不等式优化的话可以使时间复杂度降低到O(N^2)的复杂度,但是这个题目的数据范围是40000,所以这个题要用到GarsiaWachs算法,可以使时间复杂度降到O(N*logN),从而解决这个题目。

#include <algorithm>#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <list>#include <map>#include <queue>#include <set>#include <stack>#include <string>#include <vector>#define MAXN 50010#define MAXE 40#define INF 1e9#define MOD 100003#define LL long long#define ULL unsigned long long#define pi 3.14159using namespace std;int stone[MAXN];int sum = 0;int cnt = 1;void combine(int k) {    int temp = stone[k] + stone[k - 1];    sum += temp;    for (int i = k; i < cnt - 1; ++i) {        stone[i] = stone[i + 1];    }    cnt--;    int pos = k - 1;    while (pos && stone[pos - 1] < temp) {        stone[pos] = stone[pos - 1];        pos--;    }    stone[pos] = temp;    while (pos >= 2 && stone[pos] >= stone[pos - 2]) {        int d = cnt - pos;        combine(pos - 1);        pos = cnt - d;    }}int main() {    std::ios::sync_with_stdio(false);    int n;    cin >> n;    for (int i = 0; i < n; ++i) {        cin >> stone[i];    }    for (int i = 1; i < n; ++i) {        stone[cnt++] = stone[i];        while (cnt >= 3 && stone[cnt - 3] <= stone[cnt - 1]) {            combine(cnt - 2);        }    }    while(cnt > 1)        combine(cnt - 1);    cout << sum << endl;    return 0;}
原创粉丝点击