數字DP 計數問題

2021-10-10 18:13:42 字數 3008 閱讀 4218

題目鏈結

第一次做真的很難,總之十分耗費時間。

#include

#include

#include

using

namespace std;

const

int n =10;

//get前面字首部分的數值,即前面字首總方案數

intget

(vector<

int> num,

int l,

int r)

//字尾有幾位就是十的幾次方

intpower10

(int x)

//這是1到n中i出現的次數

intcount

(int n,

int x)

n = num.

size()

;//接下來是統計在當前位置上取某個數會有多少種方案

int res =0;

/* 首先要明白,x是指在這一位取x,然後去求總共的方案數

x等於0的時候要另行討論!

i從最高位開始列舉,列舉的是第i位出現了x的次數

*//*

這裡假設這個序列式abcdefg,現在i在中間位置d,其字首是abc, 字尾是efg

一、這是第i位的字首 小於 abc 的情況(當然,首先這個位置得有字首才可以)

000~abc - 1, 999種(也可以說是 10的i-1的次方 - 1 種);

二、這是字首等於abc的情況,記住!前提是字首相等!

這裡分別討論第i位的三種情況,因為這三種情況對應了不同的三種字尾的情況!

1. 第i位 大於 目標最大值的第i位,那麼字尾根本取不了,也就是0種情況。

2. 第i位 等於 目標最大的第i位

此時字尾可以隨便取,於是有0~efg這些情況

num[i] == x, 0~efg

3. 第i位 小於 目標最大的第i位

此時後面的位置可以隨便取,有1000種情況

num[i] > x, 0~999(也就是0 ~ 10的i-1的次方 - 1 種 情況)

*/for

(int i = n -1-

!x; i >=

0; i --

)//然後我們來處理字首就是abc的情況,當然啦,這裡就不管有沒有字首了,都一樣的~

//當前要取的數x 與 目標最大值的這一位數相等的時候 ,就是後面構成的數再加1(0這種情況)

if(num[i]

== x) res +

=get

(num, i -1,

0)+1

;//當前要取的數x 小於 目標最大值的這一位數 的時候,只要加上十的後面的數的位數的次方

else

if(num[i]

> x) res +

=power10

(i);

}return res;

}int

main()

return0;

}

第一次複習,對批准進行了些修改

#include

#include

#include

using

namespace std;

const

int n =10;

//get前面字首部分的數值,即前面字首總方案數

intget

(vector<

int> num,

int l,

int r)

//字尾有幾位就是十的幾次方

intpower10

(int x)

//這是1到n中x出現的次數

intcount

(int n,

int x)

n = num.

size()

;//接下來是統計在當前位置上x會有多少種方案

int res =0;

/* 首先要明白,x是指在這一位取x,然後求總共的方案數

x等於0的時候要另行討論!

i從最高位開始列舉,求第i位出現了x的數的總數

這裡假設這個序列式abcdefg,現在i在中間位置d,其字首是abc, 字尾是efg

一、這是第i位的字首 小於 abc 的情況(當然,首先這個位置得有字首才可以)

000~abc - 1, 999種(也可以說是 10的i-1的次方 - 1 種);

二、這是字首等於abc的情況,記住!前提是字首相等!

這裡分別討論第i位的三種情況,因為這三種情況對應了不同的三種字尾的情況!

1. 第i位 大於 目標最大值的第i位,那麼字尾根本取不了,也就是0種情況。

2. 第i位 等於 目標最大的第i位

此時字尾可以隨便取,於是有0~efg這些情況

num[i] == x, 0~efg

3. 第i位 小於 目標最大的第i位

此時後面的位置可以隨便取,有1000種情況

num[i] > x, 0~999(也就是0 ~ 10的i-1的次方 - 1 種 情況)

*/for

(int i = n -1-

!x; i >=

0; i --

)//然後處理字首是abc的情況,當然啦,這裡就不管有沒有字首了,都一樣的~

//當前要取的數x 與 目標最大值的這一位數相等的時候 ,就是 字尾數加1(字尾全是0 這種情況)

if(num[i]

== x) res +

=get

(num, i -1,

0)+1

;//當前要取的數x 小於 目標最大值的這一位數 的時候,只要加上十的後面的數的位數的次方

else

if(num[i]

> x) res +

=power10

(i);

}return res;

}int

main()

return0;

}

計數問題(數字dp)

給定兩個整數 a 和 b,求 a 和 b 之間的所有數字中0 9的出現次數。例如,a 1024,b 1032,則 a 和 b 之間共有9個數如下 1024 1025 1026 1027 1028 1029 1030 1031 1032 其中 0 出現10次,1 出現10次,2 出現7次,3 出現3次...

數字dp 計數問題 模板題 數字dp

數字dp目前見的比較少,最為經典的莫過於不要62,或許以前都是暴力求解。例如求解1 n中,數字x出現的次數這類題,暴力列舉每個數的時間複雜度為 o n o n o n 再列舉每一位的時間複雜度為 log 10nlog n log10n 數字一大妥妥超時。值得一提的是,2020 的藍橋杯,第一道簽到題...

演算法題 數字dp 計數問題(Python

給定兩個整數 a 和 b,求 a 和 b 之間的所有數字中0 9的出現次數。例如,a 1024,b 1032,則 a 和 b 之間共有9個數如下 1024 1025 1026 1027 1028 1029 1030 1031 1032 其中 0 出現10次,1 出現10次,2 出現7次,3 出現3次...