HDU 3506 Monkey Party(区间DP)
来源:互联网 发布:拳皇14出招优化补丁 编辑:程序博客网 时间:2024/06/10 10:17
Description
n个点1~n按顺序围成一圈,每个点有一个代价,每次可以把相邻的两个点合并成一个点,新点的代价和该次合并的代价均为这两个点的代价之和,问最后合并成一个点的最小花费
Input
第一行一整数n表示点数,之后n个整数a[i]表示第i个点的代价(1<=n<=1000,1<=a[i]<=1000)
Output
输出合并成一个点所需的最小花费
Sample Input
8
5 2 4 7 6 1 3 9
Sample Output
105
Solution
先把前n-1个数复制到第n个数后面将环上问题变成链上问题,dp[i][j]表示将区间[i,j]合并所需最小花费,轻易得到区间DP的转移方程:
dp[i][j]=min{ dp[i][k]+dp[k+1][j]+sum[i][j] },i<=k < j
(表示把该区间分成两部分分别合并然后再把这两部分合并)
sum[i][j]=a[i]+a[i+1]+…+a[j]
该转移是O(n^3)的,还要优化一下,注意到sum[i][j]满足四边形不等式和区间包含关系单调,所以可以用四边形不等式优化
两个定义:
1.w满足四边形不等式等价于对任意i<=ii<=j<=jj有w[i][j]+w[ii][jj]<=w[i][jj]+w[ii][j]
2.w关于区间包含关系单调等价于对任意i<=ii<=jj<=i有w[ii][jj]<=w[i][j]
由于a[i]均为正数,所以sum满足这里两个性质,再给出两个结论
两个结论:若m[i][j]=min( m[i][k-1]+m[k][j]+w[i][j] ),i<=k < j,且m满足上述两条性质,则有
1.m满足四边形不等式
2.令s[i][j]=max{ k | m[i][j]=m[i][k-1]+m[k][j]+w[i][j] },则s单调,即s[i][j]<=s[i][j+1]<=s[i+1][j+1]
故最开始的那个转移方程中k的范围就可以变成s[i][j-1]到s[i+1][j],可以证明这样做的时间复杂度是O(n^2)的
Code
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<map>#include<set>#include<ctime>using namespace std;typedef long long ll;#define INF 0x3f3f3f3f#define maxn 2222int n,a[maxn],sum[maxn],dp[maxn][maxn],s[maxn][maxn];int main(){ while(~scanf("%d",&n)) { for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=1;i<n;i++)a[i+n]=a[i]; sum[0]=0; for(int i=1;i<2*n;i++) { s[i][i]=i,dp[i][i]=0; sum[i]=sum[i-1]+a[i]; } for(int l=1;l<n;l++) for(int i=1;i+l<2*n;i++) { int j=i+l; dp[i][j]=INF; for(int k=s[i][j-1];k<=s[i+1][j];k++) { int temp=dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]; if(dp[i][j]>=temp)dp[i][j]=temp,s[i][j]=k; } } int ans=dp[1][n]; for(int i=1;i<n;i++)ans=min(ans,dp[i][i+n-1]); printf("%d\n",ans); } return 0;}
- HDU 3506 Monkey Party(区间DP)
- HDU 3506 Monkey Party 区间dp+四边形不等式
- hdu 3506 monkey party(环形dp)
- hdu 3506 Monkey Party (区间dp 求环形石子合并+四边形不等式优化)
- hdu 3506 Monkey Party(dp四边形优化)
- Monkey Party hdu 3506
- HDU 3506 Monkey Party
- hdu 3506Monkey Party(环形DP+平行四边形优化)
- HDU 3506 Monkey Party 【DP+四边形不等式优化】
- 【DP】 HDOJ 3506 Monkey Party
- hdu3506 Monkey Party--区间dp & 石子归并 & dp四边形优化
- Monkey Party - HDU 3506 四边形不等式优化
- HDU - 3506 Monkey Party(四边形优化)
- poj3056The Bavarian Beer Party(区间dp)
- 【HDU3506,HOJ2952】Monkey Party-环状区间合并DP+四边形不等式优化
- hdu(1520) Anniversary party(树形dp)
- HDU 1520 Anniversary party (树状dp)
- hdu 1520 Anniversary party(树dp)
- WebView的坑
- const static const static成员变量的初始化
- Raspberry上手指南(1)
- 9行Python代码搭建神经网络
- 剑指offer--递归非递归合并两个有序链表
- HDU 3506 Monkey Party(区间DP)
- 组合模式
- 重载Comparator
- IDEA快捷键
- 网站的SQL注入实战
- Apache Kylin无法启动,卡在 “Logging initialized using configuration..."
- HDU5810 Balls and Boxes
- c语言之指针和数组(一)
- thinkphp怎么显示当前服务器的地址_SERVER["SERVER_NAME"]