1. 程式人生 > >hdu 3652 B-number(數位dp)

hdu 3652 B-number(數位dp)

dir sta namespace define cto code ems memset ==

A wqb-number, or B-number for short, is a non-negative integer whose decimal form contains the sub- string "13" and can be divided by 13. For example, 130 and 2613 are wqb-numbers, but 143 and 2639 are not. Your task is to calculate how many wqb-numbers from 1 to n for a given integer n.

InputProcess till EOF. In each line, there is one positive integer n(1 <= n <= 1000000000).OutputPrint each answer in a single line.Sample Input

13

100

200

1000

Sample Output

1

1

2

2

題意:求1~n的包含13的數字 且 整除13的數的個數

思路:數位dp

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include
<cmath> #include<set> #include<list> #include<deque> #include<map> #include<queue> #define ll long long int using namespace std; inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;} int moth[13]={0,31,28,31,30,31,30
,31,31,30,31,30,31}; int dir[4][2]={1,0 ,0,1 ,-1,0 ,0,-1}; int dirs[8][2]={1,0 ,0,1 ,-1,0 ,0,-1, -1,-1 ,-1,1 ,1,-1 ,1,1}; const int inf=0x3f3f3f3f; const ll mod=1e9+7; int bits[20]; ll dp[20][20][3]; //i為數位 j為模數 k(0表示非13 1表示有1 2表示有13) ll dfs(int len,int isone,bool ismax,int modd){ if(!len){ return isone==2&&modd==0; } if(!ismax&&dp[len][modd][isone]>=0) return dp[len][modd][isone]; int up=ismax?bits[len]:9; ll ans=0; for(int i=0;i<=up;i++){ int temp=(modd*10+i)%13; if(isone==0||(isone==1&&i!=3)) //如果沒出現13 ans+=dfs(len-1,i==1,ismax&&i==up,temp); else ans+=dfs(len-1,2,ismax&&i==up,temp); } if(!ismax) dp[len][modd][isone]=ans; return ans; } ll solve(int n){ int len=0; while(n){ bits[++len]=n%10; n/=10; } return dfs(len,0,true,0); } int main(){ ios::sync_with_stdio(false); int n; while(cin>>n){ memset(dp,-1,sizeof(dp)); cout<<solve(n)<<endl; } return 0; }

hdu 3652 B-number(數位dp)