CCF 201312 4 有趣的數 數字DP

2021-08-22 19:48:45 字數 1662 閱讀 7492

ccf 201312-4 有趣的數 傳送門

這道題似乎就是所謂數字dp, 如果沒有接觸過這一類題目, 真的是很難會想出完整的方法, 畢竟有6個狀態, 然後在狀態之間進行遞推.

我們定義六種狀態, s0-s5, 對每個長度的狀態我們都從其他可能推過來的狀態推過來.

為什麼是六種? 這六種狀態是哪六種?

這些狀態分為四大類:分別有1,2,3,4個數字的情況.

只有乙個數字的狀態:

s0:只有數字2

就這一種了, 為什麼? 根據規則我們知道,0必須在1前面,2必須在3前面

所以第乙個數字一定是2,這也是所有狀態的規則

只有兩個數字的狀態:

s1:數字0,2

數字2必須為首數字

s2:數字2,3

只有三個數字的狀態:

s3:數字2,0,1

s4:數字2,0,3

四個數字全有的狀態:

s5:數字0,1,2,3

上面定義了所有可能的狀態,那麼下面就來推導一下狀態轉移,從而實現遞推過程.

對s0狀態,無論長度多少,都只能用有一種,所以方程是:

s[0][len] = 1

對s1狀態,可由s0末端加入乙個0或者上乙個s1末端加入0或2,所以方程就是

s[1][len] = s[1][len-1]*2 + s[0][len-1]

對s2狀態,可由s0末端加入乙個3或者上乙個s2末端加入3,所以方程為

s[2][len] = s[2][len-1] + s[0][len-1]

對s3狀態,可由s1末端加入乙個1或者上乙個s3末端加入1或2,所以方程為

s[3][len] = s[3][len-1]*2 + s[1][len-1]

對s4狀態,可由s2末端加入乙個0或s1末端加上3或者上乙個s4末端加入0或3,所以方程為

s[4][len] = s[4][len-1]*2 + s[2][len-1] + s[1][len - 1]

對s5狀態,可由s3末端加入3或s4末端加入1或者上乙個s5末端加入1或3,所以方程為

s[5][len] = s[5][len-1]*2 + s[3][len-1] + s[4][len-1]

按照上述狀態轉移方程, 轉移狀態即可.我們的答案就是第六個狀態s5.

100分**

#include #include #include using namespace std;

const

int mod = 1000000007;

int main()

, n;

cin >> n;

for (int

len = 1; len

<= n; ++len)

cout << s[5][n];

}

CCF 201312 4 有趣的數

時間限制 1.0s 記憶體限制 256.0mb 我們把乙個數稱為有趣的,當且僅當 1.它的數字只包含0,1,2,3,且這四個數字都出現過至少一次。2.所有的0都出現在所有的1之前,而所有的2都出現在所有的3之前。3.最高位數字不為0。因此,符合我們定義的最小的有趣的數是2013。除此以外,4位的有趣...

CCF 201312 4 有趣的數

問題描述 我們把乙個數稱為有趣的,當且僅當 1.它的數字只包含0,1,2,3,且這四個數字都出現過至少一次。2.所有的0都出現在所有的1之前,而所有的2都出現在所有的3之前。3.最高位數字不為0。因此,符合我們定義的最小的有趣的數是2013。除此以外,4位的有趣的數還有兩個 2031和2301。請計...

ccf 201312 4 有趣的數

試題編號 201312 4 試題名稱 有趣的數 時間限制 1.0s 記憶體限制 256.0mb 問題描述 問題描述 我們把乙個數稱為有趣的,當且僅當 1.它的數字只包含0,1,2,3,且這四個數字都出現過至少一次。2.所有的0都出現在所有的1之前,而所有的2都出現在所有的3之前。3.最高位數字不為0...