【训练题5:GarsiaWachs算法】石子合并 | 洛谷 P5569

石子合并 | 洛谷 P5569

难度

4 / 10 4/10 4/10
经典题

题目

放着 N N N 堆石子。每堆石子有 a i a_i ai 个石头。
每次选择相邻的两堆石子 i   ,   j i\ ,\ j i , j,把它合并成一堆新的,并获得 a i + a j a_i+a_j ai+aj分数。
计算出将该 N N N 堆石子合并成一堆的最小分数

数据范围

N ≤ 40000 N\le 40000 N40000
a i ≤ 200 a_i\le 200 ai200

思路

  • 数据范围之大,DP显然不行。
  • 我们使用 GarsiaWachs 算法(证明略)
  1. 假设第一堆左边有第零堆,第 N N N 堆右边有第 N + 1 N+1 N+1 堆,他们的石子数都是 ∞ \infin ,便于计算。
  2. 每次从左往右遍历 i i i, 找到第一个 a i − 1 < a i + 1 a_{i-1} < a_{i+1} ai1<ai+1 的位置
  3. 删除 a i − 1 、 a i a_{i-1}、a_{i} ai1ai ,记录分数 K = a i − 1 + a i K=a_{i-1}+a_i K=ai1+ai
  4. j j j i − 2 i-2 i2 向左遍历,找到第一个 a j > K a_j>K aj>K 的位置
  5. j j j 之后插入 K K K,总得分增加 K K K
  6. 循环第 2 ∼ 5 2\sim5 25步,直到找不到为止(即只剩下前后两堆 ∞ \infin 和中间一堆)。
  7. 输出总得分即可。

核心代码

时间复杂度 O ( N log ⁡ N ) O(N\log N) O(NlogN) ,可能会TLE,需要使用快读和O2优化等。

/*
 _            __   __          _          _
| |           \ \ / /         | |        (_)
| |__  _   _   \ V /__ _ _ __ | |     ___ _
| '_ \| | | |   \ // _` | '_ \| |    / _ \ |
| |_) | |_| |   | | (_| | | | | |___|  __/ |
|_.__/ \__, |   \_/\__,_|_| |_\_____/\___|_|
        __/ |
       |___/
*/
const int INF = 0x3f3f3f3f;

vector<int>V;
int work(){
    int id;
    int val;
    for(int i = 1;i < V.size() - 1;++i){
        if(V[i+1] > V[i-1]){
            val = V[i] + V[i-1];
            id = i-1;
            break;
        }
    }
    V.erase(V.begin() + id);
    V.erase(V.begin() + id);
    int id2;
    for(int i = id-1;i >= 0;--i){
        if(V[i] > val){
            id2 = i;
            break;
        }
    }
    V.insert(V.begin() + id2 + 1,val);
    return val;
}
int main()
{
    int n;n = read();
    V.push_back(INF);
    for(int i = 1;i <= n;++i){
        int t = read();
        V.push_back(t);
    }
    V.push_back(INF);
    ll ans = 0;
    for(int i = 1;i < n;++i){
        ans += work();
    }
    cout << ans;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值