当函数w(i, j)满足w(i', j) <= w(i, j'); i <= i' < j <= j' 时,称w关于关于区间包含关系单 调。
s(i, j)=k是指m(i, j)这个状态的最优决策
以上定理的证明自己去查些资料
今天看得lrj的书中介绍的 四边形优化 做个笔记,加强理解
最有代价用d[i,j]表示
d[i,j]=min{d[i,k-1]+d[k+1,j]}+w[i,j]
其中w[i,j]=sum[i,j]
四边形不等式
w[a,c]+w[b,d]<=w[b,c]+w[a,d](a<b<c<d) 就称其满足凸四边形不等式
决策单调性
w[i,j]<=w[i',j'] ([i,j]属于[i',j']) 既 i'<=i<j<=j'
于是有以下三个定理
定理一: 如果w同时满足四边形不等式 和 决策单调性 ,则d也满足四边形不等式
定理二:当定理一的条件满足时,让d[i,j]取最小值的k为K[i,j],则K[i,j-1]<=K[i,j]<=K[i+1,j]
定理三:w为凸当且仅当w[i,j]+w[i+1,j+1]<=w[i+1,j]+w[i,j+1]
由定理三知 判断w是否为凸即判断 w[i,j+1]-w[i,j]的值随着i的增加是否递减
于是求K值的时候K[i,j]只和K[i+1,j] 和 K[i,j-1]有关,所以 可以以i-j递增为顺序递推各个状态值最终求得结果 将O(n^3)转为O(n^2)
例题:
hdu 3506 Monkey Party
问题描述 :
Far away from our world, there is a banana forest. And many lovely monkeys live there. One day, SDH(Song Da Hou), who is the king of banana forest, decides to hold a big party to celebrate Crazy Bananas Day. But the little monkeys don’t know each other, so as the king, SDH must do something.
Now there are n monkeys sitting in a circle, and each monkey has a making friends time. Also, each monkey has two neighbor. SDH wants to introduce them to each other, and the rules are:
1.every time, he can only introduce one monkey and one of this monkey’s neighbor.
2.if he introduce A and B, then every monkey A already knows will know every monkey B already knows, and the total time for this introducing is the sum of the making friends time of all the monkeys A and B already knows;
3.each little monkey knows himself;
In order to begin the party and eat bananas as soon as possible, SDH want to know the mininal time he needs on introducing.
输入:
There is several test cases. In each case, the first line is n(1 ≤ n ≤ 1000), which is the number of monkeys. The next line contains n positive integers(less than 1000), means the making friends time(in order, the first one and the last one are neighbors). The input is end of file.
输出:
There is several test cases. In each case, the first line is n(1 ≤ n ≤ 1000), which is the number of monkeys. The next line contains n positive integers(less than 1000), means the making friends time(in order, the first one and the last one are neighbors). The input is end of file.
样例输入:
8
5 2 4 7 6 1 3 9
样例输出:
105
题目类型:动态规划,属于区间性质的,可以利用四边形不等式加速。
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3506
题目大意:一群猴子围成圈,每个猴子互相不认识,猴王要给大家互相认识,每个猴子认识别人需要一个时间花费,而且A猴子认识B猴子,则A猴子认识的所有猴子和B猴子认识的所有猴子都能认识,这个代价为所有AB猴子认识的猴子的时间花费和。 说的很绕,可以读下题,题目意思就是这样的。
思路:运用动态规划,枚举每个区间的分割点,从而找到最小花费。因为题目中给出的是环,解决的方法就是设一个长度为2*n的数组可以将环转化为线性。
转移方程:dp[i][j]=min(dp[i][k]+dp[k+1][j]+sum[i][j] i<k<j)
代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#define M 2000
using namespace std;
int dp[M+5][M+5],mark[M+5][M+5],sum[M+5][M+5];
int a[M+5];
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
a[i+n]=a[i];
}
memset(sum,0,sizeof(sum));
memset(dp,0,sizeof(dp));
for(int i=1;i<=2*n-1;i++)
{
for(int j=i;j<=2*n;j++)
sum[i][j]=sum[i][j-1]+a[j];
mark[i][i]=i;
dp[i][i]=0;
}
for(int t=2;t<=n;t++)
{
for(int i=1;i+t-1<=2*n;i++)
{
int j=i+t-1;
dp[i][j]=2147483647;
for(int k=mark[i][j-1];k<=mark[i+1][j];k++)
{
int tmp= dp[i][k]+dp[k+1][j]+sum[i][j];
if(tmp<dp[i][j]){
dp[i][j]=tmp;
mark[i][j]=k;
}
}
}
}
int ans=2147483647;
for(int i=1;i<=n;i++)
ans=min(ans,dp[i][i+n-1]);
printf("%d\n",ans);
}
return 0;
}