题目分析
其实就是出队入队问题,考虑如何出队入队才能让屌丝值最少,无语(写道题还虐单身狗!!)。状态转移方程不好想,具体看代码吧!!
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 105;
const int INF = 0x3f3f3f3f;
//这道题的思路有点拐弯,1自己完全晕了!!!
int val[maxn], sum[maxn], dp[maxn][maxn];
int main(){
int T, n;
scanf("%d", &T);
for(int kase = 1; kase <= T; kase++){
scanf("%d", &n);
sum[0] = 0;
for(int i = 1; i <= n; i++){
scanf("%d", &val[i]);
sum[i] = sum[i-1] + val[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 len = 1; len <= n; len++){
for(int i = 1; i+len <= n; i++){
int j = i+len;
//dp[i][j]表示对于i到j这个区间所得到的最小花费
for(int k = i; k <= j; k++) //这里表示让第i个人第k个出场,那么很明显(i+1, k)个人要在i前面出场,后面的人因为排在了前面(k-i+1)个人后面所以还需要加上对于的屌丝值
dp[i][j] = min(dp[i][j], val[i]*(k-i)+dp[i+1][k]+dp[k+1][j]+(k-i+1)*(sum[j]-sum[k]));
}
}
printf("Case #%d: %d\n", kase, dp[1][n]);
}
return 0;
}