hdu4570-区间dp

这道题的题意不是一般的难懂啊,各种查字典都没理解,还是没忍住去看了别人的博客,没想到题很简单,1-n内划分若干个区间,使的每个区间和最小,每个区间的区间和是:区间开头的数*2^区间长度. 区间dp

 1 #include<cstdio>
 2 
 3 #include<string.h>
 4 
 5 #include<algorithm>
 6 
 7 #define inf 0x3f3f3f3f
 8 
 9 typedef long long LL;
10 
11 const int maxn=100;
12 
13 using namespace std;
14 
15 int t;
16 
17 int n,m;
18 
19 LL a[maxn+10];
20 
21 LL sum[maxn+10];
22 
23 LL dp[maxn+10][maxn+10];
24 
25 void input(){
26    scanf("%d",&n);
27    memset(dp,-1,sizeof(dp));
28    for(int i=1;i<=n;i++){
29         scanf("%I64d",&a[i]);
30         sum[i]=sum[i-1]+a[i];
31    }
32 }
33 
34 LL dfs(int l,int r){
35     if(l>r) return 0;
36     if(l==r) return dp[l][r]=a[l]*2;
37     if(dp[l][r]!=-1) return dp[l][r];
38     if(r-l+1<20) dp[l][r]=a[l]*1<<(r-l+1);
39     else dp[l][r]=(sum[r]-sum[l-1])*2;
40     for(int i=l;i<r;i++){
41         dp[l][r]=min(dp[l][r],dfs(l,i)+dfs(i+1,r));
42     }
43     return dp[l][r];
44 }
45 
46 void solve(){
47    input();
48    dfs(1,n);
49    printf("%I64d\n",dp[1][n]);
50 }
51 
52 int main()
53 {
54     scanf("%d",&t);
55     while(t--){
56         solve();
57     }
58     return 0;
59 }

 

posted @ 2016-08-06 17:43  GeniusYang  阅读(104)  评论(0编辑  收藏  举报