HDU - 3652 B-number(数位DP)

本文介绍了一种使用数位DP算法解决经典问题的方法,即找出1到N范围内所有含有子字符串'13'并能被13整除的非负整数的数量。通过详细解析代码,展示了如何判断当前数是否满足条件,并提供了完整的C++实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门

B-number


Problem Description
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整除的数的个数

解题思路:经典的数位DP,难点在于怎么判断当前数能否被13整除。
 

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring> 
#include<map>
#define N 0x3f3f3f3f
#define ll long long
using namespace std;
int dp[20][20][10];
int a[20];
int dfs(int pos,int mod,int here,int flag)
{
	if(pos<=0)// 这边需要注意你存储a的时候是从0 还是 1开始存的 
	// 小编是从1开始存的 如果你是从 0 开始存的  应该 写成 pos=-1  
	return 	mod==0&&here==2;//   符合条件 
	if(!flag&&dp[pos][mod][here]!=-1)
	return dp[pos][mod][here];
	int num=flag?a[pos]:9;
	int sum=0;
	for(int i=0;i<=num;i++)
	{
		int mod2=(mod*10+i)%13;
		int here2=here;
		if(here==0&&i==1)// 如果这位是1 那么标记一下 因为 它可以组成 13 
		here2=1;
		if(here==1&&i!=1)// 如果前一位是1 且这一位不为1 那么here2=0 从新开始 
			here2=0;
	 	if(here==1&&i==3)// 如果前一位是1 且这一位不为1 那么here2=2 已经存在了 13   
			here2=2;
	 sum+=dfs(pos-1,mod2,here2,flag&&i==num);
	}
	if(!flag)
	{
		dp[pos][mod][here]=sum;
	}
	return sum;
}
int main()
{
	ll n;
	memset(dp,-1,sizeof(dp));
	while(cin>>n)
	{
		memset(a,0,sizeof(a));
		int len=0;
		while(n)
		{
			a[++len]=n%10; 
			n/=10;
		}
		int ans=dfs(len,0,0,1);
		cout<<ans<<endl;
	}
	return 0;
}

看完这道题 可以看一下这道比较类似的题目 https://blog.youkuaiyun.com/henucm/article/details/83271790

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值