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 }
View Code

 

posted @ 2014-07-03 10:41  _雨  阅读(356)  评论(0编辑  收藏  举报