You Are the One HDU - 4283 区间dp

Began to read the title to read for a long time, or refer to the chiefs of the blog
https://blog.csdn.net/codeswarrior/article/details/81479291
a group of Cock wire, each wire Cock Cock wire has a value, if the K his first play, Cock wire for the values a [i] * (k- 1), k-1 because the individual front stage in front of him, few people could be adjusted pulled into the dark room, a dark room as the stack can be advanced as to the The last person to come out, so that the final total value of the minimum Cock wire

//定义dp[i][j]表示原序列区间[i,j]的人的最小屌丝值
//枚举一个中间变量k,设i在区间[i,j]中是第k个上场的
//这样区间分成了两部分
//dp[i+1][i+k-1](k-1个人在i之前),dp[i+k][j](之后的人)
//也就是让[i,i+k-1]这些人进入小黑屋
//i先进的,那么他前面将有k-1个人
//他是第k个上场的,之后再让后面的[i+k,j]这些人上场
//这样很明显i等待了k-1个人屌丝值增长为(k-1)×a[i],而[i+k,j]这些人则等待了k个人,屌丝值增长为k×(这些人的屌丝值之和)
//因此状态转移公式为
//dp[i][j]=min(dp[i][j],dp[i+1][i+k-1]+dp[i+k][j]+k×(sum[j]-sum[i+k-1])+a[i]×(k-1))
//sum[]记录了每个人屌丝值的前缀和
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
int n,a[105],sum[105],dp[105][105];
int main() {
    int t,cas = 0;
    scanf("%d",&t);
    while(t--) {
        scanf("%d",&n);
        memset(sum,0,sizeof(sum));
        for(int i = 1; i <= n; i++) {
            scanf("%d",&a[i]);
            sum[i] = sum[i-1] + a[i];
        }
        memset(dp,0,sizeof(dp));
        for(int i = 1; i <= n; i++) {
            for(int j = i + 1; j <= n; j++) {
                dp[i][j] = INF;
            }
        }
        //区间长度 
        for(int l = 1; l < n; l++)
            //左端点,      右端点 
            for(int i = 1; i + l <= n; i++) {
                //右端点 
                int j = i + l;
                //枚举中间量,第几个上场 
                for(int k = 1; k <= j - i + 1; k++) 
                    dp[i][j] = min(dp[i][j],dp[i+1][i+k-1]+dp[i+k][j]+k*(sum[j]-sum[i+k-1])+a[i]*(k-1));
            }
        
        printf("Case #%d: %d\n",++cas,dp[1][n]);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/QingyuYYYYY/p/12470257.html