Description
Input
The next n line are n integer D1-Dn means the value of diaosi of boys (0 <= Di <= 100)
Output
Sample Input
2 5 1 2 3 4 5 5 5 4 3 2 2
Sample Output
Case #1: 20 Case #2: 24
有N个人要出场,每个人有个不爽的值,如果他第i个出场 那么 他的愤怒值为 num[i]*(i-1),求怎么样排出场顺序,能使得总得愤怒值最小
这题思维度很大,方法技巧性很强,如果一个人要进小黑屋的话就代表着他要排在后面的已经排好序的顺序后面,而且从小区间开始遍历已经将情况处理到最优,所以换位置不影响后面的最优排序
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int inf = 0x3f3f3f3f;
int dp[110][110], v[110], sum[110];
int main()
{
int t;
scanf("%d", &t);
int ncase=1;
while(t--)
{
int n;
scanf("%d", &n);
sum[0]=0;
for(int i=1;i<=n;i++)
{
scanf("%d", &v[i]);
sum[i]=sum[i-1]+v[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]=min(dp[i][j],dp[i+1][j]+sum[j]-sum[i]);
for(int k=i+1;k<=j;k++)
{
dp[i][j]=min(dp[i][j],v[i]*(k-i)+dp[i+1][k]+dp[k+1][j]+(sum[j]-sum[k])*(k-i+1));
}
}
}
printf("Case #%d: %d\n",ncase++,dp[1][n]);
}
return 0;
}