ZJOI2010 數字計數 數字DP

2021-08-18 13:17:30 字數 1138 閱讀 6909

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

輸入格式:

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

輸出格式:

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

最簡單的數字dp的題目,可以對每個數字單獨做,拿數字1舉例。

考慮dp[x][high][limit][lead],表示最高位為high的x位數中1出現的次數,其中limit表示該位是否受限,若受限,下一位的取值不能大於給定數字的第x-1位a[x-1],lead表示是否有前導0

可以算出dp[x][high][limit][lead] = sum(dp[x-1][k][limit&&k == a[x-1]][lead && k == 0]) + cal(x,high,limit,lead),若limit,k的取值從0到a[x-1],否則k的取值從0到9。cal(x,high,limit,lead)計算了最高位high對答案的貢獻,顯然當high不為1的時候貢獻為0,為1的時候計算結果為後x-1位在limit條件下的數的數量。

注意一下各種邊界條件

**:

#include #include #include using namespace std;

long long dp[20][10][2][2];

long long pow10 = ;

int a[20];

long long cal(int x,int high,bool limit,bool lead,int d)

return ans + 1;

}long long solve(int x,int high,bool limit,bool lead,int d) else

tmp += cal(x,high,limit,lead,d);

return dp[x][high][limit][lead] = tmp;

}long long solve_problem(long long x,int d)

memset(dp,-1,sizeof(dp));

return solve(len,0,true,true,d);

}int main()

cout

}

ZJOI2010 數字計數

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

ZJOI2010 數字計數

這道題題意清晰明了。最好的方法用字首差求,即 0,b 0,a 1 首先拆位把每位存到陣列中,並求出位數 l 然後把這些數當成 l 位進行統計,不足 l 位的先補字首 0 最後減去多餘的字首 0 即可。下面求 0,a 各個數出現次數的方法大體是 例如 0,1320 1320 中 l 為 4 第一位為 ...

ZJOI2010 數字計數

給定兩個正整數 a 和 b 求在 a,b 中的所有整數中,每個數碼 digit 各出現了多少次。輸入 1 99 輸出 9 20 20 20 20 20 20 20 20 20最近好像喜歡上數字dp了 這是乙個三維的dp 設 dp i j k 設從後往前填到第 i 位 這一位上的數字是 j k 這個數...