标签:ott put however chmod can begin single tput ssi
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3915 Accepted Submission(s): 1809
dp[i][j]表示区间[i,j]的最小总不开心值
把区间[i,j]单独来看,则第i个人可以是第一个出场,也可以是最后一个出场(j-i+1),也可以是在中间出场(1 ~ j-i+1)
不妨设他是第k个出场的(1<=k<=j-i+1),那么根据栈后进先出的特点,以及题目要求原先男的是排好序的,那么::
第 i+1 到 i+k-1 总共有k-1个人要比i先出栈,
第 i+k 到j 总共j-i-k+1个人在i后面出栈
举个例子吧:
有5个人事先排好顺序 1,2,3,4,5
入栈的时候,1入完2入,2入完3入,如果我要第1个人第3个出场,那么入栈出栈顺序是这样的:
1入,2入,3入,3出,2出,1出(到此第一个人就是第3个出场啦,很明显第2,3号人要在1先出,而4,5要在1后出)
这样子, 动态转移方程 就出来了,根据第i个人是第k个出场的,将区间[i,j]分成3个部分
dp[i][j]=min(dp[i][j],dp[i+1,i+k-1]+dp[i+k,j]+(k-1)*a[i]+(sum[j]-sum[i+k-1])*k);
(sum[j]-sum[i+k-1])*k 表示 后面的 j-i-k+1个人是在i后面才出场的,那么每个人的不开心值都会加个 unhappy,sum[i]用来记录前面i个人的总不开心值,根据题目,每个人的unhappy是个 累加的过程 ,多等一个人,就多累加一次
1 //2017-05-23 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 7 using namespace std; 8 9 const int N = 110; 10 const int inf = 0x3f3f3f3f; 11 int D[N], dp[N][N], sum[N]; 12 13 int main() 14 { 15 int T, n; 16 scanf("%d", &T); 17 for(int kase = 1; kase <= T; kase++){ 18 scanf("%d", &n); 19 for(int i = 0; i < n; i++){ 20 scanf("%d", &D[i]); 21 if(i == 0)sum[i] = D[i]; 22 else sum[i] = sum[i-1] + D[i]; 23 } 24 memset(dp, 0, sizeof(dp)); 25 for(int i = 0; i < n; i++) 26 for(int j = i+1; j < n; j++) 27 dp[i][j] = inf; 28 for(int len = 1; len <= n; len++){ 29 for(int l = 0; l+len <= n; l++){ 30 int r = l+len-1; 31 for(int k = 1; k <= len; k++){ 32 dp[l][r] = min(dp[l][r], dp[l+1][l+k-1]+dp[l+k][r]+(k-1)*D[l]+(sum[r]-sum[l+k-1])*k); 33 } 34 } 35 } 36 printf("Case #%d: %d\n", kase, dp[0][n-1]); 37 } 38 39 return 0; 40 }
标签:ott put however chmod can begin single tput ssi
原文地址:http://www.cnblogs.com/Penn000/p/6896503.html