HDU-4570 Multi-bit Trie

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

Multi-bit Trie

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 446    Accepted Submission(s): 169

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

题意真难懂。

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

给出一个长度为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层,所以在小于20层时初始条件:

dp[i][j]=a[i]*fun(2,(j-i+1));

大于20层是只能不压缩

dp[i][j]=(sum[j]-sum[i-1])*2;

然后循环

dp[i][j]=min(dp[i][k]+dp[k+1][j],dp[i][j]); k:i...j;

Source

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

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
__int64 dp[105][105];
 __int64 a[105],sum[105];
__int64 fun(int x,__int64 y)
{
    int i;
     __int64 ans=1;
    for(i=1;i<=y;i++)
        ans=ans*x;
    return ans;
}
int main()
{
    int i,t,n,j,k,g;
    scanf("%d",&t);
    while(t--)
    {
        memset(dp,0,sizeof(dp));
         memset(sum,0,sizeof(sum));
         memset(a,0,sizeof(a));
         scanf("%d",&n);
       for(i=0;i<n;i++)
         {
             scanf("%I64d",&a[i]);
        }
         sum[0]=a[0];
         for(i=1;i<n;i++)
             sum[i]=sum[i-1]+a[i];

        for(k=0;k<n;k++)
        {
           for(i=0;i<n-k;i++)
            {
                   j=i+k;
                   if(k<20)//区间小于20层,全压缩
                     dp[i][j]=a[i]*fun(2,(j-i+1));
                   else
                      dp[i][j]=(sum[j]-sum[i-1])*2;//区间多于20,全不压缩
               for(g=i;g<=j;g++)
               {

                   dp[i][j]=min(dp[i][j],dp[i][g]+dp[g+1][j]);

               }
            }
        }

       printf("%I64d\n",dp[0][n-1]);
    }
    return 0;
}
/*
1
7
1
2
4
4
5
4
3
*/
时间: 2024-07-28 23:10:02

HDU-4570 Multi-bit Trie的相关文章

hdu 4570 Multi-bit Trie(dp)

题目链接:hdu 4570 Multi-bit Trie 题意: 这题的题意要看半天,其实就是让你求∑ai*(2^bi),一个长度为n的数列,将其分成若干段(每一段的长度要<=20), 要求∑ai*(2^bi)最小,其中ai是每一段数列的第一项,bi是每一段的长度. 比如样例: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. 题解: 考虑dp[i]表示前i个分好后的最优解,则有dp[i]=min(dp[i

HDU 4570

E - Multi-bit Trie Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4570 Description IP lookup is one of the key functions of routers for packets forwarding and classifying. Generally, IP lookup

hdu 4825 Xor Sum(trie+贪心)

hdu 4825 Xor Sum(trie+贪心) 刚刚补了前天的CF的D题再做这题感觉轻松了许多.简直一个模子啊...跑树上异或x最大值.贪心地让某位的值与x对应位的值不同即可. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 #define CLR(a,b) memset((a)

HDU 1251 统计难题 Trie题解

基本上是标准的寻找前缀的问题,只需要insert和search函数就可以了. 我这里主要是修改一下n的记录方法,这里的n代表的不是叶子节点的标志,而是有多少单词经过了这条路径的标志. 然后是查找需要查找的前缀单词,如果没有找到,就返回0,表示没有单词以这个前缀单词为前缀,如果找到,直接返回n就是答案了.因为有n个单词经过了这条路径. 查找效率是常数. 使用静态分配空间的办法. #include <stdio.h> #include <string.h> const int MAX_

hdu 4828 Xor Sum (trie 树模板题,经典应用)

hdu 4825 题目链接 题意:给定n个数,然后给出m个询问,每组询问一个数x,问n中的数y使得x和y的异或和最大. 思路:字典树..把每个数转化成二进制,注意补全前导0,使得所有数都有相同的位数. 如果想要异或和最大,那么每一位尽可能都是1. 所以做法是,先构建字典树,然后每次find的时候,尽可能按照和当前寻找的数的位相反的位的方向走(如果有的话) 比如当前位是1,那我就往0的方向走. 需要注意的是,多组数据,每次要重新初始化一遍. 做法是 在struct 中重新 root = new N

hdu 4570 Multi-bit Trie 区间DP入门

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

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

HDU 3724 Encoded Barcodes (Trie)

题意:给n个字符串,给m个询问,每个询问给k个条形码.每个条形码由8个小码组成,每个小码有相应的宽度,已知一个条形码的宽度只有2种,宽的表示1,窄的表示0.并且宽的宽度是窄的宽度的2倍.由于扫描的时候有误差,每个小码的宽度为一个浮点型数据,保证每个数据的误差在5%内.所以一个条形码可以对应一个ASCC码,表示一个小写字母.k个条形码表示一个字符串s,每个询问表示给定的m个字符串中以s为前缀的字符串个数. 析:很容易看起来是Tire树, 不知道能不能暴过去,我觉得差不多可以,主要是在处理浮点数上,

HDU 1671 Phone List (Trie树 好题)

Phone List Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 11721    Accepted Submission(s): 3982 Problem Description Given a list of phone numbers, determine if it is consistent in the sense th

hdu 1671 Phone List (Trie树)

简单的字典树应用,在建树的时候判断就行了. 需要注意的语法: 在使用malloc和free来处理动态内存的时候,仅仅是释放了这个对象所占的内存,而不会调用这个对象的析构函数:使用new和delete就可以既释放对象的内存的同时,调用这个对象的析构函数.所以建立trie时用new更方便一些. 注意要每组数据处理完后释放动态内存(适时释放动态内存是基本素养),否则会造成内存泄漏(提交后导致MLE).还要注意有这么个知识点: delete和free都是只把指针所指向的内存释放掉了,并没有把指针本身干掉