区间动归

石子合并

链接

分析:dp[i][j]表示从i顺时针数j个位置的最大值,规划方向是顺推,初始时dp[i][i]=0。显然,我们需要求出合并个数为2,3,,,,n的情况,对于dp[i][j]我们假设最后一次合并位置为k,dp[i][j]=dp[i][k]+dp[k+1][j]+sum[i,j],因为sum[i,j]表示i到j这段和,跟k取的位置无关,由此可以得到dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]),最大值同理

 1 #include "iostream"
 2 #include "cstdio"
 3 #include "cstring"
 4 #include "string"
 5 using namespace std;
 6 const int maxn=200+10;
 7 const int INF=1<<30;
 8 int f[maxn][maxn]; //max
 9 int dp[maxn][maxn]; //min
10 int sum[maxn],a[maxn];
11 int n;
12 int main()
13 {
14     cin>>n;
15     for(int i=1;i<=n;i++){
16         cin>>a[i];
17         sum[i]=sum[i-1]+a[i];
18     }
19     for(int i=n+1;i<=2*n;i++)
20         sum[i]=sum[n]+sum[i-n];
21     for(int i=1;i<=2*n;i++)
22         for(int j=1;j<=2*n;j++)
23             dp[i][j]=INF;
24     for(int i=1;i<=2*n;i++)  dp[i][i]=0;
25     for(int l=1;l<=n;l++){
26         for(int i=1;i<=2*n-l;i++){
27             int j=i+l;
28             for(int k=i;k<j;k++){
29                 dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]);
30             }
31         }
32     }
33     memset(f,0,sizeof(f));
34     for(int l=1;l<=n;l++){
35         for(int i=1;i<=2*n-l;i++){
36             int j=i+l;
37             for(int k=i;k<j;k++){
38                 f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]+sum[j]-sum[i-1]);
39             }
40         }
41     }
42     int cnt=0,ans=INF;
43     for(int i=1;i<=n;i++)
44         cnt=max(f[i][i+n-1],cnt);
45     for(int i=1;i<=n;i++)
46         ans=min(dp[i][i+n-1],ans);
47     cout<<ans<<endl<<cnt<<endl;
48 }

时间: 2024-10-16 15:57:31

区间动归的相关文章

区间动规平行四边形优化

平行四边形优化,是一种在一类区间动规中减少时间复杂度的方法. 有方程:m(i,j)=min(m(i,k)+m(k+1,j)+w(i,j)),s(i,j)为最优点取到值. 公式:如果有w(i, j)+w(i′, j′)≤w(i′, j)+w(i, j′) 那么我们称函数 w 满足四边形不等式. 就有s(i, j)≤s(i, j + 1)≤s(i + 1, j + 1) 证明思路如下: 我们先要证明:m(i,j)+m(i′,j′)≤m(i′,j)+m(i,j′),i≤i′< j≤ j′ . 分部证明

动规之区间动规小结

区间动规主要有两种方法: 一.是先想出递归式,然后将之转化为滚动数组. 二.或者从小区间贪到大区间. POJ  1159  点击打开链接 AC代码如下: #include<iostream> #include<cstring> #include<algorithm> using namespace std; char a[5005]; short dp[5005][5005]; int min(int a,int b) { return a<b?a:b; } in

[bzoj1068]压缩[区间动规]

看了lujiaxin的blog,感觉自己好浪啊....好难过 刷题的时候不够投入,每种算法都是只写一两道就过去了,这样怎么可能进步嘛 不要总是抱怨时间太少了 都是自己不努力>_< 好啦 看题 n<=50的范围,记忆化...N^3 f[a][b][t]表示a~b这段区间内,有没有M的最短答案. 枚举断点(很重要的思想),当T==1,显然左边右边都dp一下:(think clearly) 然后,看看左边能不能被压缩,这一句很重要,因为如果区间内没有M的话,它只能是最左边复制呀复制,所以可以保

洛谷P1063 能量项链 区间动归

题目描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定等于后一颗珠子的头标记.因为只有这样,通过吸盘(吸盘是Mars人吸收能量的一种器官)的作用,这两颗珠子才能聚合成一颗珠子,同时释放出可以被吸盘吸收的能量.如果前一颗能量珠的头标记为m,尾标记为r,后一颗能量珠的头标记为r,尾标记为n,则聚合后释放的能量为m*r*n(Mars单位),新产生的珠子的头标

BZOJ1652 [Usaco2006 Feb]Treats for the Cows 区间动归

约翰经常给产奶量高的奶牛发特殊津贴,于是很快奶牛们拥有了大笔不知该怎么花的钱.为此,约翰购置了N(1≤N≤2000)份美味的零食来卖给奶牛们.每天约翰售出一份零食.当然约翰希望这些零食全部售出后能得到最大的收益.这些零食有以下这些有趣的特性: ?零食按照1..N编号,它们被排成一列放在一个很长的盒子里.盒子的两端都有开口,约翰每 天可以从盒子的任一端取出最外面的一个. ?与美酒与好吃的奶酪相似,这些零食储存得越久就越好吃.当然,这样约翰就可以把它们卖出更高的价钱. ?每份零食的初始价值不一定相同

洛谷P1018 乘积最大 区间动归

题目描述 今年是国际数学联盟确定的"2000――世界数学年",又恰逢我国著名数学家华罗庚先生诞辰90周年.在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友XZ也有幸得以参加.活动中,主持人给所有参加活动的选手出了这样一道题目: 设有一个长度为N的数字串,要求选手使用K个乘号将它分成K+1个部分,找出一种分法,使得这K+1个部分的乘积能够为最大. 同时,为了帮助选手能够正确理解题意,主持人还举了如下的一个例子: 有一个数字串:312, 当N=3,K=1时

动态规划——邮局、区间、坐标

施工中ing... 问题 A: P1045 时间限制: 1 Sec  内存限制: 128 MB 题目描述 题目很简单,给出N个数字,不改变它们的相对位置,在中间加入K个乘号和N-K-1个加号,(括号随便加)使最终结果尽量大.因为乘号和加号一共就是N-1个了,所以恰好每两个相邻数字之间都有一个符号.例如: N=5,  K=2,5个数字分别为1.2.3.4.5,可以加成: 1*2*(3+4+5)=24 1*(2+3)*(4+5)=45 (1*2+3)*(4+5)=45 -- 输入 输入文件共有二行,

HDU-5115 Dire Wolfs (区间DP)

Dire Wolf Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others)Total Submission(s): 1561    Accepted Submission(s): 897 Problem Description Dire wolves, also known as Dark wolves, are extraordinarily large and powerful

SPOJ 345 - Mixtures 区间动态规划

有n个混合物排成一排,每个混合物有一个颜色值0<=color<=99, 规定合并只能合并相邻两个, 将颜色a的混合物与颜色b的混合物合并后,颜色为( a+b ) % 100,并产生a*b的污染, 现在要将所有混合物合并,问产生污染的最小值. [区间动规]很经典的区间动规 dp[i][j] = min { dp[i][k] + dp[k+1][j] + sum[i][k]*sum[k+1][j] } 具体的DP次序详见代码: #include<cstdio> #include<