每个人都有DIAOSI 值 , 每个人产生的愤怒值 为 上场的时刻 (k-1) * a[i]
(k-1) * D 想成了 k * D一直没看出来。。。
每个人的出场次序都是不确定的,从小到大扩展的时候,对于区间 [i,j] 而言考虑 i 位置的元素的出场时刻,可能出现的 k 为i 到 j , 那么i可能上场的时刻 为 k-i到 j-i+1
对于每个区间不用考虑在整个区间中的出现次序, 在扩展时加上前面时间的 DIAOSI 值 就可以。
那么用dp[i][j] 代表从i 到 j的最小的DIAOSI 值 ,
dp[i][j] = min(dp[i][j] , (k-i) * a[i] + dp[i+1][k] + (k-i+1) * (Sum(k+1,j)) + dp[k+1][j])
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
int T;
int n;
int a[110];
int dp[105][105];
int sum[110];
int Sum(int l, int r)
{
int ans = 0 ;
for(int i = l ; i <= r ; i++)
{
ans = ans + a[i];
}
return ans;
}
int main()
{
cin >> T;
int kase = 1;
while(T--)
{
memset(dp,0,sizeof(dp));
cin >> n;
for(int i = 0 ; i < n ; i++)
{
scanf("%d",&a[i]);
}
for(int len = 0 ; len <= n ; len++)
{
for(int i = 0 ; i + len < n ; i++)
{
int j = i + len;
dp[i][j] = INF;
for(int k = i ; k <= j ; k++)
{
dp[i][j] = min(dp[i][j], (k-i) * a[i] + dp[i+1][k] + Sum(1+k,j) * (k-i+1) + dp[k+1][j]);
}
}
}
printf("Case #%d: %d\n",kase++,dp[0][n-1]);
// cout << dp[0][n-1] << endl;
}
return 0;
}
/*
Sample Input
2
5
1
2
3
4
5
5
5
4
3
2
2
Sample Output
Case #1: 20
Case #2: 24
*/