环形区间DP

区间DP的一般思考方式是:先枚举长度,再枚举开头和结尾,再枚举中间的分割点

环形区间DP一般是把环展开成链后复制成两倍,再做线性的区间DP

1068. 环形石子合并

将 n 堆石子绕圆形操场排放,现要将石子有序地合并成一堆。

规定每次只能选相邻的两堆合并成新的一堆,并将新的一堆的石子数记做该次合并的得分。

请编写一个程序,读入堆数 n 及每堆的石子数,并进行如下计算:

选择一种合并石子的方案,使得做 n?1 次合并得分总和最大。

选择一种合并石子的方案,使得做 n?1 次合并得分总和最小。

输入格式

第一行包含整数 n,表示共有 n 堆石子。

第二行包含 n 个整数,分别表示每堆石子的数量。

输出格式

输出共两行:

第一行为合并得分总和最小值,

第二行为合并得分总和最大值。

数据范围

1≤n≤200

输入样例:

4

4 5 9 4

输出样例:

43

54

#include<bits/stdc++.h>
using namespace std;
const int N=401;
int w[N],f[N][N],g[N][N],sum[N];
int main(){
    int n;
    cin>>n;
    memset(f,0x3f,sizeof f);
    memset(g,-0x3f,sizeof g);
    for(int i=1;i<=n;++i) {
        cin>>w[i];
        f[i][i]=g[i][i]=g[i+n][i+n]=f[i+n][i+n]=0;
        w[i+n]=w[i];
    }
    for(int i=1;i<=2*n;++i) sum[i]=sum[i-1]+w[i];
    for(int len=2;len<=n;++len){
        for(int st=1;st+len-1<=2*n;++st){
            int ed=st+len-1;
            for(int k=st;k<=ed;++k){
                f[st][ed]=min(f[st][ed],f[st][k]+f[k+1][ed]+sum[ed]-sum[st-1]);
                g[st][ed]=max(g[st][ed],g[st][k]+g[k+1][ed]+sum[ed]-sum[st-1]);
            }
        }
    }
    int ans1=0x3f3f3f3f,ans2=-0x3f3f3f3f;
    for(int i=1;i<=n;++i){
        ans1=min(ans1,f[i][i+n-1]);
        ans2=max(ans2,g[i][i+n-1]);
    }
    cout<<ans1<<endl<<ans2<<endl;
    return 0;
}

320. 能量项链

在Mars星球上,每个Mars人都随身佩带着一串能量项链,在项链上有 N 颗能量珠。

能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数。

并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定等于后一颗珠子的头标记。

因为只有这样,通过吸盘(吸盘是Mars人吸收能量的一种器官)的作用,这两颗珠子才能聚合成一颗珠子,同时释放出可以被吸盘吸收的能量。

如果前一颗能量珠的头标记为m,尾标记为r,后一颗能量珠的头标记为 r,尾标记为 n,则聚合后释放的能量为 mrn(Mars单位),新产生的珠子的头标记为 m,尾标记为 n。

需要时,Mars人就用吸盘夹住相邻的两颗珠子,通过聚合得到能量,直到项链上只剩下一颗珠子为止。

显然,不同的聚合顺序得到的总能量是不同的,请你设计一个聚合顺序,使一串项链释放出的总能量最大。

例如:设N=4,4颗珠子的头标记与尾标记依次为(2,3) (3,5) (5,10) (10,2)。

我们用记号⊕表示两颗珠子的聚合操作,(j⊕k)表示第 j,k 两颗珠子聚合后所释放的能量。则

第4、1两颗珠子聚合后释放的能量为:(4⊕1)=1023=60。

这一串项链可以得到最优值的一个聚合顺序所释放的总能量为((4⊕1)⊕2)⊕3)= 1023+1035+10510=710。

输入格式

输入的第一行是一个正整数 N,表示项链上珠子的个数。

第二行是N个用空格隔开的正整数,所有的数均不超过1000,第 i 个数为第 i 颗珠子的头标记,当i<N时,第 i 颗珠子的尾标记应该等于第 i+1 颗珠子的头标记,第 N 颗珠子的尾标记应该等于第1颗珠子的头标记。

至于珠子的顺序,你可以这样确定:将项链放到桌面上,不要出现交叉,随意指定第一颗珠子,然后按顺时针方向确定其他珠子的顺序。

输出格式

输出只有一行,是一个正整数 E,为一个最优聚合顺序所释放的总能量。

数据范围

4≤N≤100,

1≤E≤2.1?109

输入样例:

4

2 3 5 10

输出样例:

710

思路:对于样例\((2,3) (3,5) (5,10) (10,2)\),可以模拟成\(2,3,5,10,2\),即变成一个n+1长度的链,合并的最小区间长度是3,被合并的最小区间是2,答案是\(max(f[i][i+n])\),以及在有一个交集的区间上做合并,于是环形问题就模拟成\(2,3,5,10,2,3,5,10\),状态转移方程\(f[l,r]=max(f[l][k]+f[k][r]+w[l]*w[k]*w[r]),k>l,k<r\)

#include<bits/stdc++.h>
using namespace std;
const int N=210;
int w[N],f[N][N];
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;++i) cin>>w[i],w[i+n]=w[i];
    for(int len=3;len<=n+1;++len){
        for(int l=1;l+len-1<=n+n;++l){
            int r=l+len-1;
            for(int k=l+1;k<r;++k){
                f[l][r]=max(f[l][r],f[l][k]+f[k][r]+w[l]*w[k]*w[r]);
            }
        }
    }
    int res=0;
    for(int i=1;i<=n;++i){
        res=max(res,f[i][i+n]);
    }cout<<res<<endl;
    return 0;
}

原文地址:https://www.cnblogs.com/jjl0229/p/12639846.html

时间: 2024-07-30 01:35:44

环形区间DP的相关文章

dp乱写1:环形区间dp(数字游戏)

状态: fmax[i,j]//表示前i个数分成j个部分的最大值 fmin[i,j]//表示前i个数分成j个部分的最小值 边界:fmax[i,1]:=(sum[i] mod 10+10) mod 10(sum[i]为前i个数的总和);fmin[i,1]:=(sum[i] mod 10+10) mod 10; 状态转移方程: fmax[i,j]:=max(fmax[i,j],fmax[k,j-1]*ff(sum[i]-sum[k])); fmin[i,j]:=min(fmin[i,j],fmin[k

poj1179 环形+区间dp

因为要用到模,所以左起点设置为0比较好 #include<iostream> #include<cstdio> #include<cstring> #define INF 0x3f3f3f3f using namespace std; char c[55]; int val[55],dp_max[55][55],dp_min[55][55]; int cal(char x,int a,int b){if(x=='t')return a+b;return a*b;} in

能量项链 区间dp

能量项链 时间限制: 1 Sec  内存限制: 64 MB提交: 38  解决: 15[提交][状态][讨论版] 题目描述 每 个天顶星人都随身佩戴着一串能量项链,在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠 子,前一颗珠子的尾标记一定等于后一颗珠子的头标记.因为只有这样,通过吸盘(吸盘是天顶星人吸收能量的一种器官)的作用,这两颗珠子才能聚合成一颗珠 子,同时释放出可以被吸盘吸收的能量.如果前一颗能量珠的头标记为m,尾标记为r,后一颗

石子归并-2:区间DP{环形}

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

转载+删改:算法讲解之Dynamic Programing —— 区间DP [变形:环形DP]

发现一篇好文,可惜发现有一些地方有排版问题.于是改了一下,并加了一些自己的内容. 原文链接 对区间DP和其变式环形DP的总结. 首先先来例题. 石子归并 题目描述 Description 有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代价为两堆石子的重量和w[i]+w[i+1].问安排怎样的合并顺序,能够使得总合并代价达到最小. 输入描述 Input Description 第一行一个整数n(n<=100) 第二行n个整数w1,w2...wn (wi

区间dp与环形dp

区间dp 常见题型 求区间[1,n]XXXXX后的最大/小值,一般分为无要求或只能/最多分成m段两类 做法 如对分段无要求,设dp[i][j]表示序列中[i,j]的最值,最外层循环区间长度,第二层循环左端点,并能确定右端点,第三层枚举断点: for(rint len = 1;len <= n; ++len) {//如果对len == 1初始化了可从2枚举 for(rint i = 1,j = i + len - 1;j <= n;++i,++j) { for(rint k = i;k <

codevs1154能量项链(环形dp,区间dp)

1154 能量项链 2006年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定等于后一颗珠子的头标记.因为只有这样,通过吸盘(吸盘是Mars人吸收能量的一种器官)的作用,这两颗珠子才能聚合成一颗珠子,同时释放出可以被吸

hdu4757 最长回文子序列(区间DP)

http://acm.hdu.edu.cn/showproblem.php?pid=4745 Problem Description Long long ago, there lived two rabbits Tom and Jerry in the forest. On a sunny afternoon, they planned to play a game with some stones. There were n stones on the ground and they were

【区间DP理解】LuoGu P1063/LNSYOJ#139 能量项链/LNSYOJ#157矩阵

这又是本蒟蒻一A的一道水题 题目描述 在MarsMars星球上,每个MarsMars人都随身佩带着一串能量项链.在项链上有NN颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定等于后一颗珠子的头标记.因为只有这样,通过吸盘(吸盘是MarsMars人吸收能量的一种器官)的作用,这两颗珠子才能聚合成一颗珠子,同时释放出可以被吸盘吸收的能量.如果前一颗能量珠的头标记为mm,尾标记为rr,后一颗能量珠的头标记为r,尾标记为nn,则聚合