1. 程式人生 > 實用技巧 >數位dp之B-number

數位dp之B-number

HDU - 3652

這道題的大致意思就是給你一個數n,讓你去統計[1,n]之間含有13同時能夠被13整除的數的個數。

這是一道比較簡單的數位dp的題。主要難點是如何去計算這個數是否能夠被13整除,這裡就用到mod。

上一個位置餘數*10加上這個位子的數去%13,最後只要判斷這個餘數是否等於0就可以了。

具體程式碼如下:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 int
a[20]; 7 int dp[20][20][3]; 8 /* 9 dp[i][j][k] j表示餘數 10 k==0不包含13且不以1結尾 11 k==1 不包含13且1結尾 12 k==2 包含13 13 */ 14 int dfs(int pos,int mod,int sta,bool lim){ 15 if(pos<=0) 16 return mod==0&&sta == 2; 17 if(!lim&&dp[pos][mod][sta]!=-1) 18 return dp[pos][mod][sta]; 19
int up = lim ? a[pos] : 9; 20 int ans = 0; 21 for (int i = 0; i <= up;i++) 22 { 23 int mod1 = (mod * 10 + i) % 13;//計算餘數 24 int sta1 = sta; 25 if(sta==1&&i==3) 26 sta1 = 2; 27 else if(sta==0&&i==1) 28 sta1 = 1; 29 else
if(sta==1&&i!=1) 30 sta1 = 0; 31 ans += dfs(pos - 1, mod1,sta1, lim && i == up); 32 } 33 if(!lim){ 34 dp[pos][mod][sta] = ans; 35 } 36 return ans; 37 } 38 int solve(int x){//計算數各個位置上的值 39 int pos = 0; 40 while(x){ 41 a[++pos] = x % 10; 42 x /= 10; 43 } 44 return dfs(pos,0, 0, true); 45 } 46 int main(){ 47 int r; 48 while(~scanf("%d",&r)){ 49 memset(dp, -1, sizeof dp); 50 printf("%d\n", solve(r)); 51 } 52 }