合并石子,区间dp

#define INF 9999999
int n,a[99999],dp[9999][9999],ans=9999999,s[9999];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]),a[n+i]=a[i],s[i]=s[i-1]+a[i];
    for(int i=1;i<n;i++)
        for(int j=1;j<=n-i;j++)
        {
            dp[j][i+j]=INF;
            for (int k=j; k<i+j; k++)
            dp[j][i+j]=min(dp[j][i+j],dp[j][k]+dp[k+1][i+j]+s[i+j]-s[j-1]);
}
    printf("%d",dp[1][n]);
    return 0;
}

 int n,a[99999],dp[9999][9999],ans=9999999,s[9999];
int dfs(int l,int r)
{
    if(l==r)    {return 0;}
    else{
        int ll,rr;
        for(int i=l;i<r;i++)
        {
            if(dp[l][i])    ll=dp[l][r];
            else    ll=dfs(l,i);
            if(dp[i+1][r])    rr=dp[i+1][r];
            else    rr=dfs(i+1,r);
            dp[l][r]=99999999;
            dp[l][r]=min(dp[l][r],dfs(l,i)+dfs(i+1,r)+s[r]-s[l-1]);
        }
        return dp[l][r];
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]),a[n+i]=a[i],s[i]=s[i-1]+a[i];
        dfs(1,n);
    printf("%d  %d",dfs(1,n),dp[1][n]);
    cout<<dp[1][n];
    return 0;
}
时间: 2024-08-02 11:03:34

合并石子,区间dp的相关文章

合并石子 区间dp水题

合并石子 链接: nyoj 737 描述: 有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆.求出总的代价最小值. tags:最基本的区间dp,这题范围小,如果n大一些,还是要加个平行四边行优化. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring&g

NOI 1995 合并石子 区间DP

题目 题目描述 在一个圆形操场的四周摆放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)

石子合并(一) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述     有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆.求出总的代价最小值. 输入 有多组测试数据,输入到文件结束. 每组测试数据第一行有一个整数n,表示有n堆石子. 接下来的一行有n(0< n <200)个数,分别表示这n堆石子的数目,用空格隔开 输出 输出总代价的最小值,

zjnu 1181 石子合并(区间DP)

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

nyoj 737 石子合并(区间DP)

737-石子合并(一) 内存限制:64MB 时间限制:1000ms 特判: No通过数:28 提交数:35 难度:3 题目描述: 有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆.求出总的代价最小值. 输入描述: 有多组测试数据,输入到文件结束. 每组测试数据第一行有一个整数n,表示有n堆石子. 接下来的一行有n(0< n <200)个数,分别表示这n堆石子的数目,用空

CH5301 石子合并【区间dp】

5301 石子合并 0x50「动态规划」例题 描述 设有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,总代价为

直线石子合并(区间DP)

石子合并 时间限制:1000 ms  |  内存限制:65535 KB 描述有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆.求出总的代价最小值和最大值. 输入有多组测试数据,输入到文件结束.每组测试数据第一行有一个整数n,表示有n堆石子.接下来的一行有n(0< n <200)个数,分别表示这n堆石子的数目,用空格隔开 输出输出总代价的最小值以及最大值(中间以空格隔开)

石子合并问题 /// 区间DP oj2025

Description 在一个圆形操场的四周摆放着n堆石子.现要将石子有次序地合并成一堆. 规定每次只能选相邻的两堆石子合并成新的一堆,并将新得的这堆石子数记为该次合并的得分. 试设计一个算法,计算出将n堆石子合并成一堆的最小得分和最大得分. Input 输入的第一行是正整数n,1 ≤ n ≤100,表示有n堆石子围成环形. 第二行有n个数,分别表示每堆石子的个数. Output 输出的第一行中的数是最小得分:第二行中的数是最大得分. Sample Input 44 4 5 9 Sample O

石子合并 (区间DP)

一.试题在一个园形操场的四周摆放N堆石子(N≤100),现要将石子有次序地合并成一堆.规定每次仅仅能选相邻的两堆合并成新的一堆,并将新的一堆的石子数.记为该次合并的得分.编一程序.由文件读入堆数N及每堆的石子数(≤20).①选择一种合并石子的方案,使得做N-1次合并,得分的总和最小.②选择一种合并石子的方案,使得做N-1次合并.得分的总和最大. 比如,所看到的的4堆石子,每堆石子数(从最上面的一堆数起.顺时针数)依次为4594.则3次合并得分总和最小的方案:8+13+22=43得分最大的方案为:

合并沙子//区间dp

P1062 合并傻子 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 从前有一堆傻子,钟某人要合并他们~但是,合并傻子是要掉RP的...... 描述 在一个园形操场的四周站着N个傻子,现要将傻子有次序地合并成一堆.规定每次只能选相邻的2个傻子合并成新的一个傻子,并将新的一个傻子的RP数,记为该次合并的RP数.(合并方法与NOI1999石子合并(本题库的沙子合并)相同,请大家参考上题合并方法)将N个傻子合并成1个的最小RP数为RPn和最大RP数为RPx.钟