这道题是说有n个人要上舞台,每个人有自己的权值,每个人的不高兴值为这个人的权值乘以要等的人数,给一个初始的上台序列,有一个栈可以供你使用来调整上台的顺序。找出最优的上台顺序使得不高兴值的和最小。解决方法:区间DP,dp[x][y]表示区间x到y所能取得的最优值,注意这个区间的划分方法
View Code
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #define N 105 5 #define inf 0x7f7f7f7f 6 using namespace std; 7 int min(int a,int b) 8 { 9 return a<b?a:b; 10 } 11 int val[N],sum[N]; 12 int dp[N][N]; 13 int dfs(int i,int j) 14 { 15 if(dp[i][j]!=inf) 16 return dp[i][j]; 17 if(i>=j) 18 return 0; 19 int k; 20 for(k=0;k<=j-i;k++) 21 dp[i][j]=min(dp[i][j],dfs(i+1,i+k)+dfs(i+k+1,j)+(k+1)*(sum[j]-sum[i+k])+k*val[i]); 22 return dp[i][j]; 23 } 24 int main() 25 { 26 int t,n,i,j; 27 sum[0]=0; 28 scanf("%d",&t); 29 int icase=0; 30 while(t--) 31 { 32 scanf("%d",&n); 33 memset(dp,0x7f,sizeof(dp)); 34 for(i=1;i<=n;i++) 35 { 36 scanf("%d",&val[i]); 37 sum[i]=sum[i-1]+val[i]; 38 } 39 printf("Case #%d: %d\n",++icase,dfs(1,n)); 40 } 41 return 0; 42 }