找順數題解

2022-09-19 19:54:13 字數 2170 閱讀 6533

現在給出乙個大於1的正整數n,請你求出在1到n的正整數中,至少有乙個數字含有6的正整數個數。

輸入:100

輸出:19

很明顯,這題就是需要利用數字dp來做,通常採用數字dp的來做的題型就是:「給定某一區間,然後求出滿足某一條件的數的個數」。那麼針對這題而言的話,應該如何採用數字dp來實現這題的解答呢。

對於其給定的數n,也就是其的數字的上界,所有的數均滿足n<=n;現在將n拆分為n位數:an-1,an-2,an-3…a0;對於每一位數其範圍都是依賴於前一項的,主要是看前一項是否取到了邊界條件

舉個例子:n=23456,那麼對於第一位可以取值的範圍是0-2,而當取到2的時候,也就是達到邊界,那麼下一位的所能取到的數就是0-3了;而沒有取到2的數就無所謂了,0-9都可以取。後面的也同樣依葫蘆畫瓢。其實也就是乙個樹,見下圖:

那麼要怎樣來求解呢?本質來說其實還是列舉。首先對於這一題的要求是尋找區間範圍中為含有6的個數,那麼其實就是這n位數中只要有一位含有6就可以了。那麼首先假設在第p位上,假如其取到了6且不是上邊界,那麼後面的數就無所謂了,選什麼都可以,那麼就有10^p種方案(注意這裡位數是從0開始算的);對於是上邊界的話,這個就比較好算了,就是其該位數後面的所有上邊界組成的數再加上1(還有全是0的情況);當要不等於6的話就直接到下一位進行計算,所以再最後的演算法實現過程中是要用到遞迴的。這其實已經是大致的實現過程了,還得在判斷是否是存在限制(其實也就是受不受到上邊界的影響)。這個問題其實很好判斷,直接利用乙個flag標誌來實現就可以了,當flag=1就代表其是有限制的,為0就代表沒有限制,再向下尋找的過程中必然也要傳遞flag這個引數,那麼應該如何去傳遞呢?其實很簡單就flag&&該位是否等於上邊界;那麼就可以了。這裡可以利用寫乙個dfs函式來實現,其中包含兩個引數:當前位數,是否受限制,然後在函式中進行計數即可。

現在來分析一下時間複雜度,很顯然按照上面這麼寫的話,時間複雜度也是指數級的。那麼很顯然就過不了了,準確的說這還只是數字dp的第一步--------搜尋,第二步就是利用記憶功能(其實也就是資料暫存)。簡單的分析一下,對於第p位而言,向下尋找的話就是dfs(p-1,限制位),對於不同的p位的數,向下尋找的的也就是dfs(p-1,限制位),那麼對於所有的第p位而言,就是dfs(p-1,限制位);所以就可以利用乙個陣列來進行儲存dfs(***,***),那麼之後再使用的dfs(***,***),就可以使用該陣列來替代。那麼這樣的話,就會減少一些不必要的計算,時間複雜度就會下降至nlogn(應該沒有算錯吧,有點不確定),對於這個只有在非限制位才可以使用,當滿足條件是可以直接return該陣列中此位的數,而當不能夠return的時候,那就只能計算了,然後再將其值賦給陣列中對應的位,前提條件是非限制才可以賦值

ps:建議先理解上面的演算法,or通過下面的**來理解,然後再自己重新寫一遍

#

include

#include

#definen15

long

long a[n]

,mid[n]

;//儲存每位的邊界,mid來儲存冪指運算

long

long f[n]

;//記錄dfs,

intinit

(long

long n)

return i;

}long

long

dfs(

int p,

int flag)

//1表示約束,0表示為不是邊界

else cnt+=mid[p];}

else cnt+=

dfs(p-

1,flag&&i==right);}

if(flag==

0) f[p]

=cnt;

return cnt;

}int

main()

printf

("%lld"

,dfs

(len-1,

1));

return0;

}

閆式dp分析法

找順數 強資料版

題目描述 6 這個數字,代表 順 現在給出乙個大於1的正整數n,請你求出在1到n的正整數中,至少有乙個數字含有6的正整數個數.考試快結束了,藉此題祝各位考試順利!科科100分!新年也快到了,藉此題祝各位在新的一年裡,做什麼都是順順順!輸入 輸入乙個大於1的正整數n。1 n 1 000 000 000...

找順數 數字dp

輸出1到n中含有6的數的個數。100 19找規律感覺好難想 好像是什麼100以內有19個,200以內有19 2個,600以內115個,700以內214個.1000以內有271,2000以內有2 271個 就直接套數字dp的模板了。1 include2 include3 include4 using ...

演算法問題,找數

問題描述 從乙個正整數m中去掉任意s位後,就會得到乙個新的正整數 保留各位數字的相對位置不變 去掉不同位上的數字就會得到不同的新整數,其中有乙個最小的正整數n,問題是 再利用最小新整數n的各位數字所組成的新整數中,找出大於n的最小整數,若不存在這樣的數,測輸出0.例如,位長位6的正整數175838,...