标签:dp
1 7 1 2 4 4 5 4 3
38
/* 题意:一个长度为n的数列,将其分成若干段(每一段的长度要<=20), 要求∑ai*(2^bi)最小,其中ai是每一段数列的第一项,bi是每一段的长度。 比如:n=7,A={1 2 4 4 5 4 3},将其分成1 2 4| 4 5| 4| 3, 则其所用空间为1*2^3+4*2^2+4*2^1+3*2^1=38, 而如果分成1 2| 4 4 5| 4 3,则其所用空间为1*2^2+4*2^3+4*2^2=52,比38大。 思路:区间dp */ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> #include<stack> #include<vector> #include<set> #include<map> #define L(x) (x<<1) #define R(x) (x<<1|1) #define MID(x,y) ((x+y)>>1) #define bug printf("hihi\n") #define eps 1e-8 typedef __int64 ll; using namespace std; #define INF 0x3f3f3f3f #define N 65 ll dp[N]; ll a[N]; int n; int main() { int i,j,t; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%I64d",&a[i]); } memset(dp,INF,sizeof(dp)); for(i=n+1;i<=n+20;i++) dp[i]=0; dp[n]=a[n]*2; for(i=n;i>=1;i--) for(j=i+1;j<=min(i+20,n+1);j++)//在j这个位置分开 { dp[i]=min(dp[i],a[i]*(1<<(j-i))+dp[j]); } printf("%I64d\n",dp[1]); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:dp
原文地址:http://blog.csdn.net/u014737310/article/details/46827035