HDU 4283 You Are the One (12年天津 区间DP)

题意:有一个队列,每个人有一个愤怒值a[i],如果他是第k个上场,不开心指数就为(k-1)*a[i]。但是边上有一个小黑屋(其实就是个堆栈),可以一定程度上调整上场程序

思路:枚举区间和每个人第几个上场

dp[i][j]:[i,j]的最小分数

假设区间[i,j],第i个人第k个出场(1<=k<=j-i+1),如果第i个人第k个出场,则他之前有k-1个人出场:dp[i+1][i+k-1](应为枚举第i个人,所以从i+1开始)

然后后面剩的人又是一个子区间:dp[k+i][j]  当然在这之前有k个人先出场所以还要加上(sum[j]-sum[i+k-1])*k的值;sum[i]表示i之前所有不开心值的和

最后加上第i个人出场前的不开心值a[i]*(k-1)

dp[i][j]=min(dp[i][j],dp[i+1][k+i-1]+dp[k+i][j]+a[i]*(k-1)+(sum[j]-sum[k+i-1])*k);

 

 1 //#pragma comment(linker, "/STACK:167772160")//手动扩栈~~~~hdu 用c++交
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <iostream>
 6 #include <queue>
 7 #include <stack>
 8 #include <cmath>
 9 #include <set>
10 #include <algorithm>
11 #include <vector>
12 #include <map>
13 // #include<malloc.h>
14 using namespace std;
15 #define clc(a,b) memset(a,b,sizeof(a))
16 #define LL long long
17 const int inf = 0x3f3f3f3f;
18 const double eps = 1e-5;
19 // const double pi = acos(-1);
20 const LL MOD = 9901;
21 const int N = 110;
22 
23 // inline int r(){
24 //     int x=0,f=1;char ch=getchar();
25 //     while(ch>'9'||ch<'0'){if(ch=='-') f=-1;ch=getchar();}
26 //     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
27 //     return x*f;
28 // }
29 int a[N];
30 int dp[N][N];
31 int sum[N];
32 
33 int main(){
34     int T,n;
35     int cas=0;
36     scanf("%d",&T);
37     while(T--){
38         scanf("%d",&n);
39         sum[0]=0;
40         for(int i=1;i<=n;i++){
41             scanf("%d",&a[i]);
42             sum[i]=sum[i-1]+a[i];       
43         }
44         
45         for(int i=0;i<=n;i++){
46             for(int j=i+1;j<=n;j++){
47                 dp[i][j]=inf;
48             }
49             dp[i][i]=0;
50         }
51 
52         for(int len=1;len<n;len++){
53             for(int i=1;i<n;i++){
54                 int j=len+i;
55                 for(int k=1;k<=j-i+1;k++){
56                     dp[i][j]=min(dp[i][j],dp[i+1][k+i-1]+dp[k+i][j]+a[i]*(k-1)+(sum[j]-sum[k+i-1])*k);
57                 }
58             }
59         }
60         
61         printf("Case #%d: %d\n",++cas,dp[1][n]);   
62     }
63     return 0;
64 }

 

posted @ 2016-05-18 17:09  yyblues  阅读(215)  评论(0编辑  收藏  举报