[SCOI2009]windy数

题目:BZOJ1026、洛谷P2657。

题目大意:
给你\(A,B\),求\([A,B]\)中满足:没有前导0且相邻两位的数字相差至少为2的整数 的个数。
解题思路:
数位DP。
设\(DP{i,j}\)表示\(i\)位,最高位为\(j\)\((j可以为0)\)并满足条件的个数。
则\(DP{i,j}=\sum\limits_{k=0}^9 DP_{i-1,k}\times [|j-k|>1]\)
边界:\(DP_{1,x}=1\)。
然后分别计算\(1~A-1\)和\(1~B\)中满足条件的个数,相减即可。(BZOJ不资瓷C++11差评)

C++ Code:

#include<cstdio>
typedef int I;
I a,b,dp[15][15],dd[15];
inline I abs(const I a){return a<0?-a:a;}
void init(){
	for(I i=9;~i;--i)dp[1][i]=1;
	for(I i=1;10/++i;){
		for(I j=9;~j;--j)
		for(I k=9;~k;--k)
		if(abs(j-k)>1)dp[i][j]+=dp[i-1][k];
	}
}
inline I calc(I x){
	I len=0,ans=0;
	for(;x;x/=10)dd[++len]=x%10;
	for(I i=len;--i;)
	for(I j=9;j;--j)ans+=dp[i][j];
	for(I i=1;dd[len]>i;++i)ans+=dp[len][i];
	for(I i=len;--i;){
		for(I j=0;j<dd[i];++j)
		if(abs(dd[i+1]-j)>1)ans+=dp[i][j];
		if(abs(dd[i+1]-dd[i])<2)break;
	}
	return ans;
}
I main(){scanf("%d%d",&a,&b);init();return!printf("%d\n",calc(b+1)-calc(a));}

 

转载于:https://www.cnblogs.com/Mrsrz/p/9283315.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值