【hdu4570】Multi-bit Trie 区间DP

标签: 区间dp

hdu4570 http://acm.hdu.edu.cn/showproblem.php?pid=4570

题意:这题题意理解变态的。转自大神博客:

这题题意确实有点难懂,起码对于我这个英语渣渣来说是这样,于是去别人的博客看了下题目意思,归纳起来如下:

给出一个长度为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

用dp[i][j]表示第 i 层到第 j 层用的最少内存

初始化工作是,根据题目, 数据保证答案中的压缩不会超过20层,所以 当 j-i 小于20的时候,dp[i][j]初始化为 a[i]* 2&(j-i+1), 否则初始化为一个INF

方程 dp[i][j]= min(dp[i][j], dp[i][k]+dp[k+1][j] )   i<=k<j 

自WA点: 构造解时候,i 和 j都该逆序遍历

 1 #include <iostream>
 2 #define N 65
 3 using namespace std;
 4 
 5 const long long INF = 1LL<<50;
 6 long long dp[N][N],a[N];
 7 
 8 int main()
 9 {
10     int _;
11     cin>>_;
12     while(_--)
13     {
14         int n,i,j,k;
15         cin>>n;
16         for(i=0;i<n;i++)    cin>>a[i];
17         for(i=0;i<n;i++)
18             for(j=i;j<n;j++)
19                 if(j-i<20)  dp[i][j]=a[i]*(1<<(j-i+1));
20                 else        dp[i][j]=INF;
21         for(i=n-1;i>=0;i--)
22             for(j=n-1;j>=i;j--)
23                 for(k=i;k<j;k++)
24                     dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]);
25         cout<<dp[0][n-1]<<endl;
26     }
27     return 0;
28 }
原文地址:https://www.cnblogs.com/someblue/p/3839893.html