hdu4570Multi-bit Trie
13年长沙邀请赛的题,神题意~
题意:摘自http://blog.csdn.net/libin56842/article/details/9703457
这题题意确实有点难懂,起码对于我这个英语渣渣来说是这样,于是去别人的博客看了下题目意思,归纳起来如下:
给出一个长度为n的数列,将其分成若干段,要求最小,其中ai是每一段数列的第一项,bi是每一段的长度,l为将数列分成l段。
比如样例: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了,类似之前做过的切段。
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 using namespace std; 11 #define N 110 12 #define LL __int64 13 #define INF 1e18 14 const double eps = 1e-8; 15 const double pi = acos(-1.0); 16 const double inf = ~0u>>2; 17 LL dp[N][N],pp[65]; 18 int a[N]; 19 void init() 20 { 21 int i; 22 pp[0] = 1; 23 for(i = 1 ;i <= 64 ; i++) 24 pp[i] = pp[i-1]*2; 25 } 26 int main() 27 { 28 int i,j,n,t,g; 29 cin>>t; 30 init(); 31 while(t--) 32 { 33 scanf("%d",&n); 34 for(i = 1 ;i <= n; i++) 35 scanf("%d",&a[i]); 36 for(i = 0 ;i <= n; i++) 37 for(j = 0 ;j <= n ;j++) 38 dp[i][j] = INF; 39 if(n<=20) 40 dp[0][n] = a[1]*pp[n]; 41 for(i=1 ;i <= n; i++) 42 if(i<=20) 43 dp[1][i] = pp[i]*a[1]; 44 for(i = 2 ;i <= n; i++) 45 { 46 for(j = i ; j <= n; j++) 47 { 48 for(g = i-1; g < j; g++) 49 if(j-g>20) continue; 50 else 51 dp[i][j]= min(dp[i-1][g]+pp[j-g]*a[g+1],dp[i][j]); 52 } 53 } 54 LL minz = INF; 55 for(i = 1; i <= n; i++) 56 { 57 minz = min(minz,dp[i][n]); 58 // cout<<dp[i][n]<<" "<<i<<endl; 59 } 60 cout<<minz<<endl; 61 } 62 return 0; 63 }