hdu3652

hdu3652 B-number
传送门

题意

给出\(n(1\leq n\leq 1000000000)\),计算\([1,n]\)中有多少数既包含\(13\)又可以被\(13\)整除

题解

数位dp,从高位到低位处理,传参中有状态表示是否含有\(13\),也有当前的数除以\(13\)的余数

#include<bits/stdc++.h>
#define LL long long
#define PII pair<int,int>
using namespace std;

int n,bit[15],dp[15][15][5];

int divide(int x){
	 int cnt=0;
	 while(x){
	 	bit[cnt++]=x%10;
	 	x/=10;
	 }
	 return cnt;
}

int dfs(int pos,int rest,int sta,bool limit){
	if(pos==-1) return rest==0 && sta==2;
	if(!limit && dp[pos][rest][sta]!=-1) return dp[pos][rest][sta];
	int up=limit?bit[pos]:9;
	int ans=0;
	for(int i=0;i<=up;i++){
		if(sta==2 || (sta==1 && i==3)){
			ans+=dfs(pos-1,(rest*10+i)%13,2,limit && i==up);
		}
		else if(i==1){
			ans+=dfs(pos-1,(rest*10+i)%13,1,limit && i==up);
		}
		else{
			ans+=dfs(pos-1,(rest*10+i)%13,0,limit && i==up);
		}
	} 
	if(!limit) dp[pos][rest][sta]=ans;
	return ans;
}

int main(){
	memset(dp,-1,sizeof(dp));
	while(scanf("%d",&n)!=EOF){
		int cnt=divide(n);
		printf("%d\n",dfs(cnt-1,0,0,1));
	}
}
posted @ 2021-03-08 21:01  fxq1304  阅读(18)  评论(0编辑  收藏  举报