这道题的题意不是一般的难懂啊,各种查字典都没理解,还是没忍住去看了别人的博客,没想到题很简单,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 }