【BZOJ 3229】 [Sdoi2008]石子合并

3229: [Sdoi2008]石子合并

Time Limit: 3 Sec Memory Limit: 128 MB

Submit: 312 Solved: 148

[Submit][Status][Discuss]

Description

  在一个操场上摆放着一排N堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。

  试设计一个算法,计算出将N堆石子合并成一堆的最小得分。

Input

  第一行是一个数N。

  以下N行每行一个数A,表示石子数目。

Output

  共一个数,即N堆石子合并成一堆的最小得分。

Sample Input

4

1

1

1

1

Sample Output

8

HINT

对于 100% 的数据,1≤N≤40000

对于 100% 的数据,1≤A≤200

GarsiaWachs算法。

直接dp可以用四边形不等式优化到O(n2),用GarsiaWachs是O(nlogn)的。

简述一下GarsiaWachs算法的流程:

【假设a[0]=a[n+1]=inf】

1.从序列的左端开始找第一个a[k?1]≤a[k+1]的k,然后合并a[k?1],a[k]

2.从当前位置开始向左找第一个a[j]>a[k?1]+a[k]的j,把合并后的值插到j的后面

3.一直这样重复下去直到剩下一堆

具体算法证明:《The Art of Computer Programming》第3卷6.2.2节Algorithm G和Lemma W,Lemma X,Lemma Y,Lemma Z。

(还没有看。。)

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define LL long long
using namespace std;
int t,a[50005],n;
LL ans=0;
void Combine(int k)
{
    int tmp=a[k-1]+a[k];
    ans+=tmp;
    for (int i=k;i<t-1;i++)
        a[i]=a[i+1];
    t--;
    int j=0;
    for (j=k-1;j>0&&a[j-1]<tmp;j--)
        a[j]=a[j-1];
    a[j]=tmp;
    while (j>=2&&a[j]>=a[j-2])
    {
        int d=t-j;
        Combine(j-1);
        j=t-d;
    }
}
int main()
{
    scanf("%d",&n);
    ans=0;
    for (int i=0;i<n;i++)
        scanf("%d",&a[i]);
    t=1;
    for (int i=1;i<n;i++)
    {
        a[t++]=a[i];
        while (t>=3&&a[t-3]<=a[t-1])
            Combine(t-2);
    }
    while (t>1)
        Combine(t-1);
    cout<<ans<<endl;
    return 0;
}

感觉这道题代码实现很巧妙,证明是通过转化到树上blablabla..

时间: 2024-10-11 23:20:59

【BZOJ 3229】 [Sdoi2008]石子合并的相关文章

BZOJ 3229: [Sdoi2008]石子合并

3229: [Sdoi2008]石子合并 时间限制: 3 Sec  内存限制: 128 MB提交: 497  解决: 240[提交][][] 题目描述 在一个操场上摆放着一排N堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分. 试设计一个算法,计算出将N堆石子合并成一堆的最小得分. 输入 第一行是一个数N. 以下N行每行一个数A,表示石子数目. 输出 共一个数,即N堆石子合并成一堆的最小得分. 样例输入 4 1 1 1 1 样

3229: [Sdoi2008]石子合并

3229: [Sdoi2008]石子合并 Description 在一个操场上摆放着一排N堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分. 试设计一个算法,计算出将N堆石子合并成一堆的最小得分. Input 第一行是一个数N. 以下N行每行一个数A,表示石子数目. Output 共一个数,即N堆石子合并成一堆的最小得分. Sample Input 41111 Sample Output 8 HINT 对于 100% 的数据,

P5569 【SDOI2008】 石子合并(黑科技)

\(Solution\) 当\(n\)在\(100\)左右时,直接\(O(n^3)\)区间\(DP\) 当\(n\)在\(40000\)左右时,需要用贪心算法:加西亚-瓦克斯算法(\(Garsia\ Wachs\)) 注:这个方法仅求石子合并的最小答案 这是大概的流程 这是关于\(Garsia\ Wachs\)算法的正确性证明:传送门 时间复杂度最坏为\(O(n^2)\),但是基本跑不满,数据随机的话\(n=40000\)能搞过去 代码使用链表实现,方便删除和插入操作,边界什么的比较麻烦,一定要

石子合并的动态规划问题

题目大概都是这样的: 设有N堆沙子排成一排,其编号为1,2,3,-,N(N<=300).每堆沙子有一定的数量,可以用一个整数来描述,现在要将这N堆沙子合并成为一堆,每次只能合并相邻的两堆,合并的代价为这两堆沙子的数量之和,合并后与这两堆沙子相邻的沙子将和新堆相邻,合并时由于选择的顺序不同,合并的总代价也不相同,如有4堆沙子分别为 1  3  5  2 我们可以先合并1.2堆,代价为4,得到4 5 2 又合并 1,2堆,代价为9,得到9 2 ,再合并得到11,总代价为4+9+11=24,如果第二步

石子合并问题(直线版)

首先来个题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=737 有个更难的版本(不过很好玩):http://www.lydsy.com/JudgeOnline/problem.php?id=3229 题目: 石子合并(一) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述     有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价

2298 石子合并 2008年省队选拔赛山东

题目描述 Description 在一个操场上摆放着一排N堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分. 试设计一个算法,计算出将N堆石子合并成一堆的最小得分. 输入描述 Input Description 第一行是一个数N. 以下N行每行一个数A,表示石子数目. 输出描述 Output Description 共一个数,即N堆石子合并成一堆的最小得分. 样例输入 Sample Input 4 1 1 1 1 样例输出 S

四边形不等式优化DP——石子合并问题 学习笔记

好方啊马上就要区域赛了连DP都不会QAQ 毛子青<动态规划算法的优化技巧>论文里面提到了一类问题:石子合并. n堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分. 求出将n堆石子合并成一堆的最小得分和最大得分以及相应的合并方案. 设m[i,j]表示合并d[i..j]所得到的最小得分. 状态转移方程: 总的时间复杂度为O(n3). [优化方案] 四边形不等式: m[i,j]满足四边形不等式 令s[i,j]=max{k | m[

zjnu1181 石子合并【基础算法?动态规划】——高级

Description 在操场上沿一直线排列着 n堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的两堆石子合并成新的一堆, 并将新的一堆石子数记为该次合并的得分.允许在第一次合并前对调一次相邻两堆石子的次序. 计算在上述条件下将n堆石子合并成一堆的最小得分. Input 输入数据共有二行,其中,第1行是石子堆数n≤100: 第2行是顺序排列的各堆石子数(≤20),每两个数之间用空格分隔. Output 输出合并的最小得分. Sample Input 3 2 5 1 Sample Out

洛谷 P1880 石子合并

题目描述 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分. 输入输出格式 输入格式: 数据的第1行试正整数N,1≤N≤100,表示有N堆石子.第2行有N个数,分别表示每堆石子的个数. 输出格式: 输出共2行,第1行为最小得分,第2行为最大得分. 输入输出样例 输入样例#1: 4 4 5 9 4 输出样例#1: 43 54 区间dp