hdu3652 B-number 数位dp

本文介绍了一个基于深度优先搜索(DFS)的算法实现,用于解决特定的数学问题:寻找不超过给定数字且能被13整除的正整数个数,其中该整数必须包含数字1和3。通过递归地枚举每一位数字的可能性,并利用动态规划减少重复计算,最终高效地得出答案。

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

dfs版本

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int num[15];
int dp[15][15][3];
//dp[i][j][k]
//i:数位
//j:余数
//k:3种状态,0-没有1,1-有1,2-有13

//pos为当前处理的数位(权重表示法,也就是剩下pos+1位待填数)
//mod-余数,have-状态;
//lim-后面的数是否可以任意填,1-不可以,0-可以
int dfs(int pos,int mod,int have,int lim)
{
    int n,i,ans=0,mod_x,have_x;

    //余数为0,有13,返回一种结果
    if(pos<=0)
        return mod==0&&have==2;

    //已经搜索过了
    if(!lim&&dp[pos][mod][have]!=-1)
        return dp[pos][mod][have];

    //判断本位枚举的范围
    n=lim?num[pos]:9;
    for(i=0;i<=n;i++)
    {
        mod_x=(mod*10+i)%13;//重新计算余数
        have_x=have;
        if(have==0&&i==1)
            have_x=1;
        if(have==1&&i!=1)
            have_x=0;
        if(have==1&&i==3)
            have_x=2;
        ans+=dfs(pos-1,mod_x,have_x,lim&&i==n);
    }

    //dp[pos][mod][have]要保存的是pos之后可以任意填的结果
    //存在dfs(...,1)和dfs(...,0)的区别,如果lim=1时,记录dp可能会导致错误
    //所以每一次dfs(...,1)都要重新计算
    if(!lim)
        dp[pos][mod][have]=ans;
    return ans;
}

int main()
{
    int n,i;
    while(~scanf("%d",&n))
    {
        memset(num,0,sizeof(num));
        memset(dp,0xff,sizeof(dp));
        i=0;
        while(n)
        {
            num[++i]=n%10;
            n/=10;
        }
        printf("%d\n",dfs(i,0,0,1));
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值