高精度压位

唔...很久没讲算法之类的了...

这次讲一个我认为比较黑科技的东东——高精度压位

普通高精度

先从普通的高精度来讲起。

高精度实际上是将每一位上的数看做一个数放在数组里,再模拟人工计算。  

实际数为 123456 (本文最低位(这里就是'6'这个数字) 位数标为1,原因是适应实际运算最高位会改变,而下标不会往负方向减少,即下标没有负的)

这个就是将一个数处理后的样子,之后就可以模拟人工计算将答案算出。

高精度压位

然后就是压位技巧啦,其实压位技巧很简单...这样考虑,我们是用数组保存每一个数的,但是这个数组其实可以保存更大的数,而不是一个一位数。由此发现,压位优化了空间。

所以,压位是什么,画图啦~。

 

 

实际数: 12 34 56 (两个两个看便是压位)

这就是压位,将一个一位数,变成两位数,压在同一个下标当中。

如何简单的理解压位呢,不如将这个数,看成100进制,这样就是两位数了。

那压位之后的高精度,有什么变化么?

对于计算而言,基本没有,因为在计算过程中只是将模数改为100而已(原来是10,模数即过程中考虑进位时需要取模)。

对于输出而言,有一个比较明显的变化  补0输出。

举个栗子嘿嘿,问问神奇海螺(某博客有趣的小梗,出自海绵宝宝)?

如这样一个数要输出   :     

    50002005

将其压位(压为两位数):

              50 00 20 05

而数组里保存的可没有前导0,它是这样的:

           50   0  20  5

此时如果直接输出就与原始数不同了,所以除了最后位(即从左往右数第一位非0数) 外,都要补0。

例题:

  NOIP1997第三题街道路径

  这是一个很常见的dp,先不考虑高精度。

  dp[i][j] 表示到达i,j的方案数。

  考虑将题目中给的矩阵a[i][j]赋值为1表示不可以走。

   方程就是 dp[i][j]=dp[i-1][j]+dp[i][j-1]    (a[i][j]!=1要可以走才行,对于a[i-1][j]或a[i][j-1]是否为1无需考虑,因为dp[i-1][j],dp[i][j-1]会是0,对答案不影响)

    就是可以从左往右走,也可以从上往下走。

   题目要求保留20位,可是20位已经超过longlong了。

   正常想法就是高精度了,可是,试试用压位简化代码。

   设dp[i][j][0]表示答案的前10位,dp[i][j][1] 表示答案的后10位,这样合起来就是20位。 (注意10位需要longlong int 为 10^9)

   先不考虑进位那么

     dp[i][j][0]=dp[i-1][j][0]+dp[i][j-1][0];

        dp[i][j][1]=dp[i-1][j][1]+dp[i][j-1][1];

  再考虑进位,dp[i][j][1]是最低位,要向dp[i][j][0] 进位。

        进位过程就是dp[i][j][1]%=1e10     dp[i][j][0]+=dp[i][j][1]/1e10   (1e10为10^10,就是压10位)

  这个就是压位了,注意压位不一定只像前文说的压成100,当然1000    10000等等都是可以压的。

posted @ 2018-06-28 22:21  Bunnycxk  阅读(400)  评论(0编辑  收藏  举报