HDU 4570 Multi-bit Trie(区间dp)

Multi-bit Trie

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 539    Accepted Submission(s): 214

Problem Description

  IP lookup is one of the key functions of routers for packets forwarding and classifying. Generally, IP lookup can be simplified as a Longest Prefix Matching (LPM) problem. That‘s to find the longest prefix in the Forwarding Information
Base (FIB) that matches the input packet‘s destination address, and then output the corresponding Next Hop information.

  Trie-based solution is the most wildly used one to solve LPM. As shown in Fig.1(b), an uni-bit trie is just a binary tree. Processing LPM on it needs only traversing it from the root to some leaf, according to the input packet‘s destination address. The longest
prefix along this traversing path is the matched one. In order to reduce the memory accesses for one lookup, we can compress some consecutively levels of the Uni-bit Trie into one level, transforming the Uni-bit Trie into a Multi-bit Trie.

  For example, suppose the strides array is {3, 2, 1, 1}, then we can transform the Uni-bit Trie shown in Fig.1(b) into a Multi-bit Trie as shown in Fig.1(c). During the transforming process, some prefixes must be expanded. Such as 11(P2), since the first stride
is 3, it should be expanded to 110(P2) and 111(P2). But 110(P5) is already exist in the FIB, so we only store the longer one 110(P5).

  Multi-bit Trie can obviously reduce the tree level, but the problem is how to build a Multi-bit Trie with the minimal memory consumption (the number of memory units). As shown in Fig.1, the Uni-bit Trie has 23 nodes and consumes 46 memory units in total,
while the Multi-bit Trie has 12 nodes and consumes 38 memory units in total.

Input

  The first line is an integer T, which is the number of testing cases.

  The first line of each case contains one integer L, which means the number of levels in the Uni-bit Trie.

  Following L lines indicate the nodes in each level of the Uni-bit Trie.

  Since only 64 bits of an IPv6 address is used for forwarding, a Uni-bit Trie has maximal 64 levels. Moreover, we suppose that the stride for each level of a Multi-bit Trie must be less than or equal to 20.

Output

  Output the minimal possible memory units consumed by the corresponding Multi-bit Trie.

Sample Input

1
7
1
2
4
4
5
4
3

Sample Output

38

Source

2013 ACM-ICPC长沙赛区全国邀请赛——题目重现

Recommend

/*
题意:一个长度为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;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-09 23:09:00

HDU 4570 Multi-bit Trie(区间dp)的相关文章

HDU 4960 Another OCD Patient 区间dp

区间dp.. T^T一直感觉是n^3,看了题解看来是数据水了么.. #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string.h> #define ll long long #define inf 1e8 inline int min(int a, int b){return a<b?a:b;} inline void rdl(ll

hdu 4570 Multi-bit Trie 区间DP入门

Multi-bit Trie 题意:将长度为n(n <= 64)的序列分成若干段,每段的数字个数不超过20,且每段的内存定义为段首的值乘以2^(段的长度):问这段序列总的内存最小为多少? 思路:区间的最值,区间DP; 枚举长度,在初始化时,将长度和20比较,小于20看成是一段,大于20时,因为不能压缩,直接全部分割就是了:之后枚举区间内部的所有值,这是并不需要考虑将这个区间一分为二后各自的长度是否大于20,因为在子结构中已经计算好了:直接去最优解即可: #include<iostream>

hdu 5151 Sit sit sit(区间dp+排列组合)

题目链接:hdu 5151 Sit sit sit 题意: 一共有并排N个椅子, N个学生依次去坐,同时满足3个条件就不能坐下去: 1,该椅子不在最左,不在最右. 2,该椅子左右都有人坐了. 3,左右的椅子不同颜色.求最后N个人都能坐下去,有多少不同的情况. 题解: 考虑区间dp,dp[i][j] = sum(dp[i][k-1] * dp[k+1][j] * c[j - i][k - i])其中满足(v[k-1]==v[k+1]) 表示i到j区间最后来坐k位置,乘组合是因为合并这两段区间的时候

HDU 2476 String painter(区间DP啊)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2476 Problem Description There are two strings A and B with equal length. Both strings are made up of lower case letters. Now you have a powerful string painter. With the help of the painter, you can cha

HDU 2476 String painter (区间DP)

题意:给出两个串a和b,一次只能将一个区间刷一次,问最少几次能让a=b 思路:首先考虑最坏的情况,就是先将一个空白字符串刷成b需要的次数,直接区间DP[i][j]表示i到j的最小次数. 再考虑把a变成b的次数 ans[i]:a从(0,i)变成b(0,i)所需的最小次数 初始化ans[i]=dp[0][i] 如果a[i]==b[i],则ans[i]=ans[i-1]; 由小区间更新到大区间 1 //#pragma comment(linker, "/STACK:167772160")//

hdu 5115 Dire Wolf(区间dp)

Problem Description Dire wolves, also known as Dark wolves, are extraordinarily large and powerful wolves. Many, if not all, Dire Wolves appear to originate from Draenor. Dire wolves look like normal wolves, but these creatures are of nearly twice th

HDU 4960 Another OCD Patient(区间dp记忆化搜索)

题目大意:给你一串数字让你判断经过若干次合并,使得这个数字串变成回文串的最小成本是多少.第一行是数字串,第二行是合并连续i个数字的成本是多少. 解题思路:区间dp,可以进行记忆化搜索,如果左边比右边和大那么右边一定是小了,右边比左边大那么左边一定小了.因为保证有解.具体不太好说,直接看代码吧. Another OCD Patient Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe

HDU 5115 Dire Wolf ——(区间DP)

比赛的时候以为很难,其实就是一个区间DP= =..思路见:点我. 区间DP一定要记住先枚举区间长度啊= =~!因为区间dp都是由短的区间更新长的区间的,所以先把短的区间更新完.. 代码如下: 1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 using namespace std; 5 const int N = 200 + 5; 6 const int inf = 0x3f3f3f3

HDU 5151 Sit sit sit 区间dp

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5151 题解: 有n个椅子,编号为1到n. 现在有n个同学,编号为1到n,从第一个同学开始选择要坐的位子,并且这个同学不能坐同时满足下面三个条件的椅子. 1.左右都有相邻的位子 2.左右相邻的位子都是空的. 3.左右两边的位子颜色不同. 问总共有多少种坐法. 题解: dp[i][j]表示坐满编号为i到j的椅子的类数. 现在第一个开始坐的人选择的是第t个位子,则dp[i][j]+=dp[i][t-1]

HDU ACM 4597 Play Game -&gt;区间DP+记忆化搜索

分析:两个人都足够聪明,因此每个阶段都拿最大的.dp[sa][ea][sb][eb]分别表示区间1的开始为sa,结束为ea,区间2的开始为sb,结束为eb时能拿到的最大值.之后分别从四个方向上拿,是个搜索的过程. [cpp] view plaincopyprint? #include<iostream> using namespace std; int dp[25][25][25][25];  //dp[sa][ea][sb][eb],分别表示区间1的开始,结束,区间2的开始,结束 int a