区间dp-------------You Are the One

you are the one
这个题还没怎么整明白,先转载一遍别人的
转载出处:https://blog.csdn.net/Jianzs_426/article/details/77455491

#include 
#include 
#include 
using namespace std;
const int INF = (1<<27);
int n;
int a[105];
int sum[105];
int dp[105][105];
int main() {
    int _;
    scanf("%d", &_);
    for(int ka = 1; ka <= _; ka++) {
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            sum[i] = sum[i-1]+a[i];
        }
        // 全局变量默认为0,并不更新为INF,所以,每次只需初始化其他状态点。
        for(int i = 0; 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 <= n-l; i++) {  // 起始位置
                int j = i+l;  // 终止位置
                for(int k = i; k <= j; k++)  // 第i个人在i-j中第k个上场
                    dp[i][j] = min(dp[i][j],
                      dp[i+1][k]+a[i]*(k-i)+dp[k+1][j]+(k+1-i)*(sum[j]-sum[k]));
            }
        }
        printf("Case #%d: %d\n", ka, dp[1][n]);
    }
    return 0;
}

你可能感兴趣的:(笔记)