問題描述1、這道題先進行題目的分析(解題思想的確定)如果乙個自然數n的k進製表示中任意的相鄰的兩位都不是相鄰的數字,那麼我們就說這個數是k好數。求l位k進製數中k好數的數目。例如k = 4,l = 2的時候,所有k好數為11、13、20、22、30、31、33 共7個。由於這個數目很大,請你輸出它對1000000007取模後的值。
輸入格式
輸入包含兩個正整數,k和l。
輸出格式
輸出乙個整數,表示答案對1000000007取模後的值。
樣例輸入
4 2樣例輸出
7
如果乙個自然數n的k進製表示中任意的相鄰的兩位都不是相鄰的數字,那麼我們就說這個數是k好數。求l位k進製數中k好數的數目。那麼,可以知道,是要對l位,各個數字上的數字進行分析。先假設第一位上的數字(範圍是0~k-1),然後對後邊加入的每一位數字進行分析,要求新加入的數字與前一位的數字的差的絕對值不為1。
這是乙個滿足「將待求解的問題分為若干個相互聯絡的子問題」,這一思路的題目。所以,應該使用動態規劃的思路來解題。
2、確定如何具體的實現動態規劃
因為動態規劃的解題整體思路是:將待求解的問題分為若干個相互聯絡的子問題,即「重複子問題」,只在第一次遇到的時候求解,然後將這個子問題的答案儲存,在選擇的時候是從以前求出的若干個與本步驟相關的子問題中選最優的那個,加上這一步的值來構成這一步那個子問題的最優解 。
所以先要對如何進行 對前面的子問題答案中選擇 本步驟相關的子問題中選最優的那個。所以,先對於本問題簡單的情況進行分析:
①先分析題目所給範例:k=4 l= 2
其中,行表示數最高位的數字(<4,其實最高位不可以是0,但是因為在動態規劃的過程中需要使用到這種情況,所以就將這種情況列出來,只是在計算最終的可能情況數時,不加入最高位時0的情況即可),
列表第幾位(<=l)
注:i表示是幾位數時的情況
j表示最高位數字是 幾 的情況
本題的思路是:最高位為 j 時,那麼與它相鄰的位數(次高位)一定要滿足與他的差值不能為1(次高位跟最高位不是相鄰數字)。按照這個思路遞推,從 j=l,到 j=1的情況。
i\j012
3111
1123
223如果,你覺得這種情況太過於簡單,沒辦法讓你更好的理解動態規劃的過程。那我們來進行稍微複雜的情況的分析:
k=5 l= 3
注意:**的第二行,即位數為1時,是對l=1的情況的說明,也是為l>1的情況賦的初值
注:i表示是幾位數時的情況
j表示最高位數字是 幾 的情況
本題的思路是:最高位為 j 時,那麼與它相鄰的位數(次高位)一定要滿足與他的差值不能為1(次高位跟最高位不是相鄰數字)。按照這個思路遞推,從 j=l,到 j=1的情況。
|i\j01
2341
1111
1243
3343
1410
1110
14這樣下來,你應該對具體的動態規劃過程有所了解了吧。
3、完整的源**如下:(藍橋杯已通過)
#include
#include
#include
#define basic 1000000007
intmain()
}for
(j=1
;j) sum+
=dp[l]
[j];
sum%
=basic;
printf
("%d"
,sum)
;return0;
}
我之前不會動態規劃,所以參考了大神的博文,自己又單步除錯了很久,才想明白了以上的思路。如有不妥,歡迎指正!
參考的博文為:大佬的原博文
另外,關於memset函式的用法,可以參考我另外的一篇博文,詳細了解。
藍橋杯 K好數(動態規劃,C )
問題描述 如果乙個自然數n的k進製表示中任意的相鄰的兩位都不是相鄰的數字,那麼我們就說這個數是k好數。求l位k進製數中k好數的數目。例如k 4,l 2的時候,所有k好數為11 13 20 22 30 31 33 共7個。由於這個數目很大,請你輸出它對1000000007取模後的值。輸入格式 輸入包含...
藍橋杯 K好數 DP
問題描述 如果乙個自然數n的k進製表示中任意的相鄰的兩位都不是相鄰的數字,那麼我們就說這個數是k好數。求l位k進製數中k好數的數目。例如k 4,l 2的時候,所有k好數為11 13 20 22 30 31 33 共7個。由於這個數目很大,請你輸出它對1000000007取模後的值。輸入格式 輸入包含...
藍橋杯 k好數dp
演算法訓練 k好數 時間限制 1.0s 記憶體限制 256.0mb 問題描述 如果乙個自然數n的k進製表示中任意的相鄰的兩位都不是相鄰的數字,那麼我們就說這個數是k好數。求l位k進製數中k好數的數目。例如k 4,l 2的時候,所有k好數為11 13 20 22 30 31 33 共7個。由於這個數目...