题意:给定每个diaosi的不开心值D,如果他第x个上场,他会有(x-1)*D的不开心值,因为他等了x-1个人,有一个小黑屋类似于栈,可以使用它来改变顺序,求最少的不开心值。
做法:首先dp[i][j]还是表示i到j区间的最优值,然后还是三层循环,最主要的就是短点了。首先预处理所有人的等待时间的前缀和sum[i]。
短点k表示区间i到j中i是第k个出去的
g[i][j]=min(g[i][j],g[i+1][k]+g[k+1][j]+(k-i)*a[i]+(k-i+1)*(sum[j]-sum[k]));
既然是第k个出去肯定增加了(k-i)*a[i]的不愉快,同时后面的所有也增加了(k-i+1)*(sum[j]-sum[k])的不愉快
#include<bits/stdc++.h>
using namespace std;
const int N = 110;
int n,a[N],sum[N],g[N][N];
int main()
{
//ios::sync_with_stdio(false);
//cin.tie(0);
//cout.tie(0);
int T,n,kase=1;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
sum[0]=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
sum[i]=sum[i-1]+a[i];
}
memset(g,0,sizeof(g));
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
g[i][j]=0x3f3f3f3f;
for(int l=2;l<=n;l++)
{
for(int i=1;i<=n-l+1;i++)
{
int j=i+l-1;
for(int k=i;k<=j;k++)
{
g[i][j]=min(g[i][j],g[i+1][k]+g[k+1][j]+(k-i)*a[i]+(k-i+1)*(sum[j]-sum[k]));
}
}
}
printf("Case #%d: %d\n",kase++,g[1][n]);
}
return 0;
}