計數問題(數字dp)

2021-10-06 15:21:27 字數 1784 閱讀 7625

給定兩個整數 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次等等…

輸入格式

輸入包含多組測試資料。

每組測試資料佔一行,包含兩個整數 a 和 b。

當讀入一行為0 0時,表示輸入終止,且該行不作處理。

輸出格式

每組資料輸出乙個結果,每個結果佔一行。

每個結果包含十個用空格隔開的數字,第乙個數字表示『0』出現的次數,第二個數字表示『1』出現的次數,以此類推。

資料範圍

0輸入樣例:

1 10

44 497

346 542

1199 1748

1496 1403

1004 503

1714 190

1317 854

1976 494

1001 1960

0 0

輸出樣例:

1 2 1 1 1 1 1 1 1 1

85 185 185 185 190 96 96 96 95 93

40 40 40 93 136 82 40 40 40 40

115 666 215 215 214 205 205 154 105 106

16 113 19 20 114 20 20 19 19 16

107 105 100 101 101 197 200 200 200 200

413 1133 503 503 503 502 502 417 402 412

196 512 186 104 87 93 97 97 142 196

398 1375 398 398 405 499 499 495 488 471

294 1256 296 296 296 296 287 286 286 247

思路(數字dp&&記憶化搜尋dfs) 

用f[i][j]表示滿足從右往左列舉到第i位時,目標數字出現次數為j的數字的個數;

數字dp統計1-n中x中x出現的總次數,利用字首和的思想,[a,b]**現的次數即為:dp(b)-dp(a-1)   b>a;

數字dp具體的實現步驟:

用乙個陣列num來儲存n的每一位的數值,然後每次對於1-n中的每乙個數字,用dfs從高位到低位依次列舉,按照數字dp的思想,記憶化搜尋中統計f[i][j]。

完整**:

#include #include #include #define int long long

using namespace std;

const int maxn=2010;

int f[10][maxn],num[10];

int a,b;

int dfs(bool lead,bool limit,int pos,int x,int sum)//有無前導零、當前位的數字是否達到了上限、當前位、要找的數x、x的出現總次數

return lead&&!limit?f[pos][sum]=res:res;

}int dp(int n,int x)//return 1-n中x出現的次數

return dfs(0,1,cnt,x,0);

}signed main()

cout<}

return 0;

}

數字DP 計數問題

題目鏈結 第一次做真的很難,總之十分耗費時間。include include include using namespace std const int n 10 get前面字首部分的數值,即前面字首總方案數 intget vector int num,int l,int r 字尾有幾位就是十的幾次...

數字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次...