hdu 3506 Monkey Party(dp四边形优化)

来源:互联网 发布:ubuntu vi 撤销命令 编辑:程序博客网 时间:2024/05/19 10:15

题意:

一群猴子围成圈,每个猴子互相不认识,猴王要给大家互相认识,每个猴子认识别人需要一个时间花费,而且A猴子认识B猴子,则A猴子认识的所有猴子和B猴子认识的所有猴子都能认识,这个代价为所有AB猴子认识的猴子的时间花费和。

很明显的环形的区间dp和取石子问题很像。

状态方程:dp[i][j]= max{ dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1] }

注意一点:区间类dp的四边形标记和非区间类的有点不同,具体要体会理解。

#include<iostream>#include<math.h>#include<stdio.h>#include<algorithm>#include<string.h>#include<vector>#include<map>using namespace std;typedef __int64 lld;#define oo 0x3f3f3f3f#define maxn 2005int dp[maxn][maxn],mark[maxn][maxn];int val[maxn],sum[maxn];int main(){    int n,m,T;    while(scanf("%d",&n)!=EOF)    {        for(int i=1;i<=n;i++)        {            scanf("%d",&val[i]);            val[i+n]=val[i];        }        sum[0]=0;        for(int i=1;i<2*n;i++)            sum[i]=sum[i-1]+val[i];        memset(dp,0,sizeof dp);        for(int i=1;i<=2*n;i++)        {            dp[i][i]=0;            mark[i][i]=i;        }        for(int L=2;L<=n;L++)        {            for(int i=1;i+L-1<=2*n;i++)            {                int j=i+L-1;                dp[i][j]=oo;                for(int k=mark[i][j-1];k<=mark[i+1][j];k++)                    if(dp[i][j]>dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1])                    {                        dp[i][j]=dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1];                        mark[i][j]=k;                    }            }        }        int ans=oo;        for(int i=1;i<=n;i++)            ans=min(dp[i][i+n-1],ans);        printf("%d\n",ans);    }    return 0;}





0 0
原创粉丝点击