HDU3506 Monkey Party【Section DP】

Topic link:  HDU3506 Monkey Party

Question: Similar to merging stones in a circle, the cost of merging two piles of stones is the sum of the number of the two piles of stones. Ask the minimum cost of merging all stones;

Analysis: dp[i][j] represents the minimum cost of the interval [i,j], p[i][j] represents the number of stones in the interval [i,j], adding quadrilateral inequality optimization, s[i][ j] represents the best breakpoint in the interval [i,j];

 

[Optimization of Quadrilateral Inequality]

When a<b<=c<d, if f[a][c]+f[b][d]<=f[b][c]+f[a][d], f satisfies the quadrilateral Inequality, at this time the best breakpoint s[i][j] satisfies the property:

s[i][j-1]<=s[i][j]<=s[i+1][j]

In this way, the original enumeration interval start point and breakpoint n*n are optimized to n

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=2007;
int dp[maxn][maxn],s[maxn][maxn],p[maxn][maxn],a[maxn];
int n,ans;
void rua()
{
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),a[i+n]=a[i];
    memset(dp,INF,sizeof(dp));
    memset(s,0,sizeof(s));
    for(int i=1;i<=n+n;i++)
    {
        dp[i][i]=0;
        s[i][i]=i;
        p[i][i]=a[i];
    }
    for(int i=1;i<n;i++)//区间长度
        for(int j=1;i+j<2*n;j++)//区间起点
            for(int k=s[j][i+j-1];k<=s[j+1][i+j];k++)
            {
                int tmp=p[j][k]+p[k+1][i+j];
                if(dp[j][i+j]>dp[j][k]+dp[k+1][i+j]+tmp)
                {
                    p[j][i+j]=tmp;
                    dp[j][i+j]=dp[j][k]+dp[k+1][i+j]+tmp;
                    s[j][i+j]=k;
                }
            }
    ans=INF;
    for(int i=1;i<=n+1;i++) ans=min(ans,dp[i][i+n-1]);
    printf("%d\n",ans);
}
int main()
{
    while(~scanf("%d",&n)) rua();
    return 0;
}

 

Guess you like

Origin blog.csdn.net/qq_43813163/article/details/102554453