HDU 5787 K-wolf Number(数位DP)

本文介绍了一种使用数位动态规划(DP)解决特定数位模式计数问题的方法,即在一个区间内找出所有相邻k个数位都不相同的数字个数。通过递归枚举并检查当前位与前k-1位是否相同来实现,特别处理了前导0的情况。

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

Description
给出一个区间[L,R],问这个区间中任意相邻k个数位均不相同的数字个数
Input
多组用例,每组用例输入三个整数L,R,k,以文件尾结束输入
(1<=L<=R<=1e18,2<=k<=5)
Output
对于每组用例,输出[L,R]中满足条件的数字个数
Sample Input
1 1 2
20 100 5
Sample Output
1
72
Solution
数位DP,记录当前位前四位的值,枚举当前位数字时判断其与前面k-1个数字是否相同,不同才能放,注意一点是前置0的问题,为避免前置0与当前位放0冲突,可以将前置0赋为10
Code

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
ll dp[22][11][11][11][11],L,R;
int k,a[22];
bool check(int v1,int v2,int v3,int v4,int v)
{
    if(k==2)return v!=v4;
    if(k==3)return v!=v4&&v!=v3;
    if(k==4)return v!=v4&&v!=v3&&v!=v2;
    if(k==5)return v!=v4&&v!=v3&&v!=v2&&v!=v1;
}
ll dfs(int pos,int v1,int v2,int v3,int v4,int fp)
{
    if(pos==0)return v4!=10;
    if(!fp&&dp[pos][v1][v2][v3][v4]!=-1)return dp[pos][v1][v2][v3][v4];
    int fpmax=fp?a[pos]:9;
    ll ans=0;
    for(int i=0;i<=fpmax;i++)
    {
        if(i==0&&v4==10)ans+=dfs(pos-1,10,10,10,10,fp&&i==fpmax);
        else if(check(v1,v2,v3,v4,i))ans+=dfs(pos-1,v2,v3,v4,i,fp&&i==fpmax);
    }
    if(!fp)dp[pos][v1][v2][v3][v4]=ans;
    return ans;
}
ll Solve(ll n)
{
    int res=0;
    while(n)
    {
        a[++res]=n%10;
        n/=10;
    }
    return dfs(res,10,10,10,10,1);
}
int main()
{
    while(~scanf("%I64d%I64d%d",&L,&R,&k))
    {
        memset(dp,-1,sizeof(dp));
        printf("%I64d\n",Solve(R)-Solve(L-1));
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值