洛谷——P2657 [SCOI2009]windy数

P2657 [SCOI2009]windy数

题目大意:

windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道,

在A和B之间,包括A和B,总共有多少个windy数?

思路:

其实挺简单的,算是数位DP入门级别的题吧,特别要注意限制,如果没有前导0和没有最高位限制就不能返回,反之答案是错误的,(原来前导0也很重要!)

设dp[pos][j]表示第pos位上一位是j的方案数,然后记搜即可。

记忆化搜索:

#include<bits/stdc++.h>

using namespace std;

int a,b,shu[20],dp[20][10],k;

int dfs(int pos,int state,bool lead,int limit){
    if(pos==0) return 1;
    if(!limit&&!lead&&dp[pos][state]) return dp[pos][state];
    int cnt=0,up=limit?shu[pos]:9;
    for(int i=0;i<=up;i++){
        if(abs(state-i)<2&&!lead) continue;
        cnt+=dfs(pos-1,i,lead&&!i,limit&&i==shu[pos]);
    }
    return !limit&&!lead ? dp[pos][state]=cnt : cnt;
}

int slove(int x){
    k=0;
    while(x){
        shu[++k]=x%10;
        x/=10;
    }
    return dfs(k,-1,true,true);
}

int main()
{
    scanf("%d%d",&a,&b);
    printf("%d\n",slove(b)-slove(a-1));
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/song-/p/9614807.html