B-number (数位DP)

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.

Input
Process till EOF. In each line, there is one positive integer n(1 <= n <= 1000000000).
Output
Print each answer in a single line.
Sample Input
13
100
200
1000
Sample Output
1
1
2
2
题意:求从1到n,含有13且能够被13整除的数的个数


代码

#include<stdio.h>
#include<string.h>
using namespace std;
typedef long long ll;
int a[20];
int dp[20][15][3];
//dp[pos][mod][have] 
//pos:当前位置
//mod:余数
//have :0:前一位不是1 1:前一位是1 2:有13  
ll Dfs(int pos,int mod,int have,bool limit){
	int modx,havex;
	if(pos==-1) return mod==0&&have==2;
	if(!limit&&dp[pos][mod][have]!=-1) return dp[pos][mod][have];//没有上限并且已被访问过
	int up=limit?a[pos]:9;
	ll cnt=0,i;
	for(i=0;i<=up;i++){
	   modx=(mod*10+i)%13;
	   havex=have;
	   if(have==0&&i==1) havex=1;
	   if(have==1&&i!=1) havex=0;
	   if(have==1&&i==3) havex=2;
	   cnt+=Dfs(pos-1,modx,havex,limit&&i==a[pos]);
	}
	if(!limit) dp[pos][mod][have]=cnt;
	return cnt;
}
ll solve(ll x){
	int pos=0;
	while(x){
		a[pos++]=x%10;
		x/=10;
	}
	return Dfs(pos-1,0,0,true);
}
int main(){
	ll n;
	memset(dp,-1,sizeof(dp));
	while(scanf("%lld",&n)!=EOF){
		printf("%lld\n",solve(n));
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值