hdu2829 Lawrence

题目链接:戳我

朴素DP:\(dp[i][j]=dp[i-1][k]+cost[k+1][j]\)
其中dp[i][j]表示炸第i次的时候,处理到前j个的最小值是多少。cost[i][j]表示的是i,j联通的情况下的贡献。

之后可以套用四边形不等式优化,然后将复杂度降低到\(O(n^2)\)

注意hdu不支持

#ifndef ONLINE_JUDGE
#endif

加了之后会WA的qwqwq

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define MAXN 1010
using namespace std;
int n,m;
long long dp[MAXN][MAXN],s[MAXN][MAXN],cost[MAXN][MAXN],a[MAXN],sum[MAXN];
int main()
{
    while(scanf("%d%d",&n,&m)==2)
    {
        if(n==0||m==0) break;
        memset(dp,0x3f,sizeof(dp));
        memset(s,0,sizeof(s));
        memset(cost,0,sizeof(cost));
        for(int i=1;i<=n;i++) 
            scanf("%lld",&a[i]),sum[i]=sum[i-1]+a[i];
        for(int i=1;i<=n;i++)
            for(int j=i+1;j<=n;j++)
                cost[i][j]=cost[i][j-1]+(sum[j-1]-sum[i-1])*a[j];
        // for(int i=1;i<=n;i++)
        //     for(int j=i+1;j<=n;j++)
        //         printf("cost[%d][%d]=%lld\n",i,j,cost[i][j]);
        for(int i=1;i<=n;i++)
        {
            dp[0][i]=cost[1][i];
            s[0][i]=1;
            s[i][n+1]=n-1;
        }
        for(int i=1;i<=m;i++)
        {
            for(int j=n;j>i;j--)
            {
                for(int k=s[i-1][j];k<=s[i][j+1];k++)
                {
                    if(dp[i-1][k]+cost[k+1][j]<dp[i][j])
                    {
                        dp[i][j]=dp[i-1][k]+cost[k+1][j];
                        s[i][j]=k;
                    }
                }
            }
        }
        printf("%lld\n",dp[m][n]);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/fengxunling/p/10702427.html
hdu