1. 程式人生 > >Hello,I'm Proking.

Hello,I'm Proking.

題目要求求好數,因為好數不太好求,所以可以逆向思維,求“壞數”。

對於1~n的壞數如何求呢?

step1:

轉化二進位制(設轉化的序列為a,長度為len)。

step2:

對於一個數是否是壞數很明顯分:

這個數轉成二進位制後成度小於len和等於len。

小於len的很好求。

我們先前可以求出一個f[i,'0'/'1','0','1'](表示這個數由i位組成,第i位是0/1,第i-1位是0/1)然後答案很明顯就是f[i,1,0]+f[i,1,1] 

那麼對於等於len的又如何求呢?

很明顯,我們只需列舉len位上的每一位,當第i位上的ai為1時才有可能對答案有貢獻(自己想想,因為可以把這一位改為0,且求出改成0後所組成的數所能構造的方案數)

例如,當n=13

a=[1,0,1,1](轉化時儲存的是從後往前)

len=4

很明顯第一位我們不可能改變,第二位因為是1則可以考慮轉化成0。

所以,方案數很明顯是f[i+1,a[i+1],0]。

但還需判斷把這一位改為0後,是否與i+1和i+2位構成了一個好數,如果構成好數則不能加這個方案數。為什麼?自己想。非常容易想到。

與此同時,如果前面出現了連續的111或000則直接break,否則答案是會錯的。為什麼?自己想。非常容易想到。

加f[i+1,a[i+1],0]?為什麼?為什麼判斷第i位,反而加的是f[i+1...]的值?自己想。非常容易想到。