数位DP入门 + 待补上最后一题

本文深入解析数位DP的基本思想及其实现技巧,并通过两道经典题目——HDU2689不要62和BZOJ1026Windy数——进行实战演练,帮助读者掌握数位DP的应用。

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

学了一下数位DP后才会做范老师的题目。

HDU2689不要62
模板题 , dfs写法,大概理解数位dp的思想以及简洁的写法。limit:是否受限,zero:是否一直在前导零。数位dp的精髓在于记忆化搜索。

#include<bits/stdc++.h>
using namespace std;

const int N = 10000;

int dp[N][2] , l , r , ans , a[N] , cnt;

int dfs(int pos  ,int six , int limit) {
    if(!pos) return 1;
    if(!limit && dp[pos][six] != -1) return dp[pos][six];
    int up = limit ? a[pos] : 9;
    int res = 0;
    for(int i = 0;i <= up;i ++) {
        if(i == 4) continue;
        if(six && i == 2) continue;
        res += dfs(pos - 1, i == 6, a[pos] == i && limit);
    }
    if(!limit) dp[pos][six] = res;
    return res;
}

int solve(int x) {
    cnt = 0; 
    while(x) {
        a[++ cnt] = x % 10;
        x /= 10;
    }
    return dfs(cnt , 0 , 1);
}

int main() {
    memset(dp,-1,sizeof(dp));
    while(scanf("%d%d",&l,&r) == 2 && l + r) {
        printf("%d\n",solve(r) - solve(l - 1));
    }
}

BZOJ1026 Windy数
考虑前导零和limit细节不多,模版思路跟着走即可。

#include<bits/stdc++.h>
using namespace std;

const  int N = 35;

int dp[N][15] , n , m , l , r , cnt , a[N];

int dfs(int pos ,int limit , int lead, int sta) {
    if(!pos) return 1;
    if(!limit && !lead && dp[pos][sta] != -1) return dp[pos][sta];
    int up = limit ? a[pos] : 9;
    int res = 0;
    for(int i = 0;i <= up;i ++) {
        if(abs(i - sta) <= 1) continue;
        res += dfs(pos - 1 , a[pos] == i && limit , lead && (!i),(lead && (!i)) ? -100 : i);
    }
    if(!limit && !lead) dp[pos][sta] = res;
    return res; 
}  

int solve(int x) {
    cnt = 0;
    while(x) {
        a[++ cnt] = x % 10;
        x /= 10;
    }
    return dfs(cnt , 1 , 1 , -100);
}

int main() {
    memset(dp,-1,sizeof(dp));
    scanf("%d%d",&l,&r);
    printf("%d\n",solve(r) - solve(l - 1));
}

最后就是一道比较神的数位DP,范老师的T3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值