您的位置:首页 > 其它

hdu4570 Multi-bit Trie

2014-05-13 17:37 295 查看

Multi-bit Trie

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

Total Submission(s): 383 Accepted Submission(s): 146



[align=left]Problem Description[/align]
  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.

[align=left]Input[/align]
  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.

[align=left]Output[/align]
  Output the minimal possible memory units consumed by the corresponding Multi-bit Trie.

[align=left]Sample Input[/align]

1
7
1
2
4
4
5
4
3[align=left]Sample Output[/align][code]38


哎我对自己无语了,居然这道题wa了4次。

题目大概意思:给你一列数,然后划分为小20的子数列,并且划分后的子数列的第一个数乘2的数列个数的次方,并相加,求最小值。

例如 1 2 4 4 5 4 3 可以划分为1 和2 4 4 5 4 3 其值为1*2*1+2*2的6次方;

也可以划分为 1 2 和4 4 5 4 3 其值为1*2的2次方+4*2的5次方。

。。。。。。。。

当然还有很多种。

算法其实就是矩阵连乘的思想。

思想:

我们如果一步一步的推导,不难发现会有很多的重叠的子问题,这些子问题我们可以用一个数组来存储,就可以节约很多时间。

有了重叠我们是不是考虑一下是子问题和最后问题是否有关系。答案的肯定的。

不难发现比如 1
和2 4 4 5 4 3的划分时那么我们是不是还有找2 4 4 5 4 3中最小划分。

这样我们就可以发现要求dp[i][j]的最大值是不是dp[i][k]+dp[k+1][j];k是划分的位置;

当然对于这个题我们还得注意一下用什么去存储,int果断是不行的因为我就是应为int错了好几次。至于问什么自己去算吧!

#include<stdio.h>
#include<math.h>
#include<string.h>
__int64 min(__int64 a,__int64 b)
{
return a>b?b:a;
}
__int64 pow(int n)
{
__int64 a=1;
for(int i=0;i<n;i++)
a*=2;
return a;
}
int main()
{
__int64 dp[70][70];
__int64 a[70],sum[70];
int n,i,j,k,l,s;
scanf("%d",&l);
while(l--)
{
scanf("%d",&n);
for(i=1;i<=n;i++)
{
sum[i]=0;
scanf("%I64d",&a[i]);
sum[i]=sum[i-1]+a[i];
}
memset(dp,0,sizeof dp);
for(s=0;s<n;s++)
for(i=1;i<=n&&i+s<=n;i++)
{
j=s+i;
if(s<=19)//注意只有前19个需要压缩。因为只有前19个才能划分。
dp[i][j] =min((sum[j]-sum[i-1])*2,a[i]*pow(j-i)*2);
else//后面无需划分所以不用划分。
dp[i][j] = (sum[j]-sum[i-1])*2;
for(k = i; k<j; k++)
dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]);
}
printf("%I64d\n",dp[1]
);

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: