1. 程式人生 > >B-number (數位DP)

B-number (數位DP)

B-number

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7977    Accepted Submission(s): 4700


Problem DescriptionA 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 Input13 100 200 1000
Sample Output1 1 2 2
Authorwqb0039
Source

題意:

找ab區間內被13整除且含有13的個數。

POINT:

dp[x][y][z]代表當前x位數對13取模等於y,z代表有麼有13的狀態,1代表前一個數是“1”,2代表有“13”了,0代表其他情況。

#include <iostream>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define LL long long
const int inf = 0x3f3f3f3f;

int dp[20][13][3];
int num[20]    ;

int dfs(int now,int mod,int sta,bool limit)
{
	if(!limit&&dp[now][mod][sta]!=-1) return dp[now][mod][sta];

	if(now==0)
		return mod==0&&sta==2;

	int maxx=limit?num[now]:9;

	int ans=0;

	for(int i=0;i<=maxx;i++){
		int to;
		if(sta==2||(sta==1&&i==3)){
			to=2;
		}
		else if(i==1){
			to=1;
		}else{
			to=0;
		}
		ans+=dfs(now-1,(mod*10+i)%13,to,limit&&i==maxx);
	}


	if(!limit) dp[now][mod][sta]=ans;

	return ans;
}


int solve(int x)
{
	int cnt=0;
	while(x){
		num[++cnt]=x%10;
		x/=10;
	}
	return dfs(cnt,0,0,true);
}


int main()
{
	memset(dp,-1,sizeof dp);
	int a;
	while(~scanf("%d",&a)){
		printf("%d\n",solve(a));

	}



}