DP问题之数位DP

本文介绍了数位动态规划(DP)方法,通过f[i][j]来计算n位数中满足相邻数差不超过1的整数个数。讲解了状态转移方程、边界条件和一个具体的Atcoder比赛题目实例。AC代码展示了如何使用数位DP解决该问题。

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

数位DP是一种计数用的dp,一般就是要统计一个区间 [ l,    r ]内满足一些条件数的个数。所谓数位dp,字面意思就是在数位上进行dp咯。数位还算是比较好听的名字,数位的含义:一个数有个位、十位、百位、千位......数的每一位就是数位啦!

也就是说到处理问题时与数的临位数位之间的联系时,可以优先考虑数位DP,注意到记忆化搜索也是可行的,这取决于个人喜好,总之我们通常称之为数位DP问题。

经典例题:Atcoder Beginner Conteset 242 C

给你一个整数n,问 由n位 数字,每一位上的数字在一到九之间,所组成的数中,相邻位的两个数之差的绝对值不大于一的 数有多少个。

设 f[ i ] [ j ] 表示n 位 10 进制整数以 j 开头 的 符合要求的 数的个数;(数位DP最常见的设法)

状态转移方程为 f [ i ] [ j ]=f [ i-1 ] [ j-1  ] +f[ i-1 ] [  j ]+f[ i-1 ] [ j+1 ]     

需要注意边界和初始条件。(避免出现数组下标为负数,和初始化赋值问题);

AC 代码:


#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
const int MOD=998244353;
typedef long long ll;
ll n;
ll ans=0;
ll f[N][10];
int main(){
ll n;
cin>>n;
    for(int i=1;i<=n;i++)
    {
		for(int j=1;j<=9;j++)
		{
			if(i==1)f[i][j]=1;
			   else {
					if(j==1) f[i][j]=f[i-1][j]+f[i-1][j+1];
					if(j==9) f[i][j]=f[i-1][j]+f[i-1][j-1];
					else f[i][j]=f[i-1][j-1]+f[i-1][j]+f[i-1][j+1];
				    f[i][j]%=MOD;
					  
			        }
	
		
			
			
		  }
	  }
                for(int i=1;i<=9;i++)
                ans+=f[n][i],ans%=MOD;
                cout<<ans<<endl;
	            return 0;
	
}

​

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

litian355

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值