线性DP 四边形不等式优化 hdu3506

当函数w(i,j)满足 w(a,c)+w(b,d) <= w(b,c)+w(a,d) 且a<=b< c <=d 时,我们称w(i,j)满足四边形不等式。。
 
当函数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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值