HDU 2089 不要62(数位DP)

本文介绍了一种解决特定类型数学问题的方法——数位DP。通过一个实例问题讲解了如何运用数位DP来求解避免特定数字的组合计数问题,并提供了详细的代码实现。

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

题目链接:点击打开链接

题意:中文题目,很显然

思路:数位DP入门,DP函数有四个参量,当前位置,前一位的数字,前一位是否为6,前几位取值是否都是上限。dp[i][state]表示第i位在limit(limit对应第四个参量)取0时,该state状态下(state对应第三个参量)剩余位数(包括本位)取值满足条件的方案和。

// HDU 2089 不要62.cpp 运行/限制:0ms/1000ms
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
int dp[10][2];
int upper, dig[10];
int DP(int pos, int pre, int state, int limit) {//位置 前一位的数字 前一位是否为6 前几位是否是上限
	if (pos == -1) {
		return 1;
	}
	if (!limit && dp[pos][state] != -1) {
		return dp[pos][state];
	}
	int re = 0;
	int top = limit ? dig[pos] : 9;
	for (int i = 0; i <= top; i++) {
		if (i == 4) continue;
		if (pre == 6 && i == 2) continue;
		re += DP(pos - 1, i, i == 6, limit && i == dig[pos]);
	}
	if (!limit) dp[pos][state] = re;
	return re;
}
int solve(int num) {
	upper = 0;
	while (num) {
		dig[upper++] = num % 10;
		num /= 10;
	}
	return DP(upper - 1, -1, 0, 1);
}
int main(){
	int n, m;
	memset(dp, -1, sizeof(dp));//优化:dp数组在此初始化,能节省很多时间,因为在limit取0时,dp数组的取值只和数位有关,和测试数据的范围无关
	while (scanf("%d%d", &n, &m) != EOF && n && m) {
		printf("%d\n", solve(m) - solve(n - 1));
	}
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值