數字DP入門 BZOJ 1833 題解(需要複習)

2021-08-02 03:51:00 字數 1374 閱讀 2796

顯然,這篇部落格受popoqqq的影響,**自己敲了一遍,基本上和popoqqq的**一樣,在這裡寫一下題解

題目:

time limit: 3 sec memory limit: 64 mb

submit: 3421 solved: 1510

給定兩個正整數a和b,求在[a,b]中的所有整數中,每個數碼(digit)各出現了多少次。

輸入檔案中僅包含一行兩個整數a、b,含義如上所述。

輸出檔案中包含一行10個整數,分別表示0-9在[a,b]中出現了多少次。

1 99
9 20 20 20 20 20 20 20 20 20
30%的資料中,a<=b<=10^6;

100%的資料中,a<=b<=10^12。

注釋**:

#include

#include

#include

#include

#define dnt long long

using namespace std;

dnt cnt[10],f[100];

void resolve(dnt x,dnt pos)

} void digital_dp(dnt x,int ff)

for(j=1;j<=9;j++)

}now=pos/=10;i--;//此時的now等於最高位的意義

//注意到pos大於了x才停止迴圈,所以往回走一步

while(now

now+=pos;//該位的意義一步一步地累加到now裡去

}pos/=10;i--;

}} int main()

//首先預處理出每一位數字包括前導0的i位數裡有多少它,注意一點,所有的數在某一位包括前導0的情況下個數都是相等的,舉個例子,對於小於十位數來說,所有數出現的機會是均等的,小於兩位數,每個數出現的機會也是均等的,注意這裡處理的是有前導0的,也就是說01,03,09這些都是合法的

cin>>a>>b;

digital_dp(b+1,1);//注意到這裡是b+1,參看該函式裡用的是統計小於該數的資訊,也就剛好是1到b的資訊

digital_dp(a,-1);//函式傳的引數1,-1到ff裡,是為了實現乙個函式實現區間1到b減去區間1到a-1的操作

for(i=0;i<=9;i++)

printf("%lld

%c",cnt[i],i==9?'\n':' ');

//注意到這裡的輸出,我pe了一次

BZOJ 1833 數字計數 數字DP

題目鏈結 做的第一道數字dp題,聽說是最基礎的模板題,但還是花了好長時間才寫出來。想深入了解下數字dp的請點這裡 先設dp陣列dp i j k 表示數字是i,以j開頭的數k出現的次數 有數字dp的題一般都會用到字首陣列,題目要求我們求b a這個區間裡各個數碼出現的次數,我們可以分別求出 0,b 和 ...

BZOJ1833 count 數字計數

題目描述 給定兩個正整數a和b,求在 a,b 中的所有整數中,每個數碼 digit 各出現了多少次。輸入輸入檔案中僅包含一行兩個整數a b,含義如上所述。輸出輸出檔案中包含一行10個整數,分別表示0 9在 a,b 中出現了多少次。樣例輸入 1 99樣例輸出 9 20 20 20 20 20 20 2...

BZOJ 1833 count 數字計數

題目描述 給定兩個正整數a和b,求在 a,b 中的所有整數中,每個數碼 digit 各出現了多少次。輸入輸入檔案中僅包含一行兩個整數a b,含義如上所述。輸出輸出檔案中包含一行10個整數,分別表示0 9在 a,b 中出現了多少次。樣例輸入 1 99樣例輸出 9 20 20 20 20 20 20 2...