【思路,dp,BigInteger】ZOJ - 2598 Yet Another Digit
Posted on 2015-08-18 10:08 LLGemini 阅读(168) 评论(0) 编辑 收藏 举报
【redundant binary - 冗余二进制】:由0,1,2构成的二进制形式,基数还是2。
现给你一十进制数n,问其可转化成多少种冗余二进制形式。
首先要想到:2x = 2*2x-1 也就是说 10 <=> 02;20 <=> 12;
10000
-> 10000
-> 02000
-> 01200
-> 01120
-> 01112
从上面可以看出,第一位的1保持不变时,有1种冗余二进制形式;第一位的1变为0时,其后有多少个0存在,就有多少种冗余二进制形式;
从低位向高位看,每到一个1进行计算,记a为该位的1保持不变的方案数,b为该位的1变成0存在的方案数。记录该位1与上一位1之间连续0的个数。初始有a[0]=1,b[0]=0,c=0。
则(从低位向高位)第i个1保持不变的方案数a[i] = 上一位的1保持不变的方案数a[i-1] + 上一位的1变为0的方案数b[i-1];
(从低位向高位)第i个1变为0的方案数b[i] = 上一位的1保持不变的方案数a[i-1]*c + 上一位的1变为0的方案数b[i-1]*(c+1);
(注意此处的c+1,因为上一位1变成0后,该位1与上一个非零位之间会多出一个0来,即c+1个0;
举例说明:10100001
step1: 右边第1位为1,此时c=0; a[1] = a[0] + b[0] = 1;
(10100001)
b[1] = a[0]*0 + b[0]*1 = 0;
step2: 右边第6位为1,此时c=4; a[2] = a[1] + b[1] = 1;
(10100001)-> a[1]
b[2] = a[1]*4 + b[2]*5 = 4;
(10020001)-> a[1]*4
(10012001)
(10011201)
(10011121)
step3: 右边第8位为1,此时c=1; a[3] = a[2] + b[2] = 5;
(10100001) -> a[2]
(10020001) -> b[2]
(10012001)
(10011201)
(10011121)
b[3] = a[2]*1 + b[2]*2 = 9;
(02100001) -> a[2]*1
(02020001) -> b[2]*2
(01220001)
(02012001)
(01212001)
(02011201)
(01211201)
(02011121)
(01211121)
最后的答案就是a[n]+b[n]。
附代码:
1 import java.math.BigInteger; 2 import java.util.Scanner; 3 4 5 public class Main { 6 7 public static void main(String[] args) { 8 // TODO Auto-generated method stub 9 Scanner cin = new Scanner(System.in); 10 11 while(cin.hasNext()) 12 { 13 BigInteger n = cin.nextBigInteger(); 14 if (n.signum() < 0) break; 15 BigInteger a = BigInteger.ONE, b = BigInteger.ZERO; 16 int c = 0; 17 for(int i = 0; i < n.bitLength(); i++) 18 { 19 if(n.testBit(i)) 20 { 21 BigInteger a_ = a.add(b); 22 BigInteger b_ = a.multiply(BigInteger.valueOf(c)).add(b.multiply(BigInteger.valueOf(c+1))); 23 c = 0; 24 a = a_; 25 b = b_; 26 } 27 else 28 c++; 29 } 30 System.out.println(a.add(b)); 31 } 32 cin.close(); 33 } 34 }