[BZOJ] ]1026: [SCOI2009]windy数

需要记录的信息有:做到了第几位,上一位的数字,是否随便填

记搜实现起来实在是方便,数位DP应该不会卡常数

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;

inline int rd(){
  int ret=0,f=1;char c;
  while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
  while(isdigit(c))ret=ret*10+c-'0',c=getchar();
  return ret*f;
}
#define space() putchar(' ')
#define nextline() putchar('\n')
void pot(int x){if(!x)return;pot(x/10);putchar('0'+x%10);}
void out(int x){if(!x)putchar('0');if(x<0)putchar('-'),x=-x;pot(x);}

const int MAXN = 22;

int f[MAXN][MAXN];

int a[MAXN],top;
int dfs(int dp,int lst,bool lim){
    if(dp==0)return 1;
    if(!lim&&lst>=0&&f[dp][lst]!=-1)return f[dp][lst];
    int ret=0,up=(lim?a[dp]:9),pos;
    for(int i=0;i<=up;i++){
        if(abs(i-lst)<2) continue;  
        pos=i;
        if(i==0&&lst==-3) pos=-3;
        ret+=dfs(dp-1,pos,lim&(i==up));
    }
    if(!lim&&lst>=0) f[dp][lst]=ret;
    return ret;
}

int solve(int x){
    top=0;
    while(x){
        a[++top]=x%10;
        x/=10;
    }
    memset(f,-1,sizeof(f));
    return dfs(top,-3,1);
}

int main(){
    int L,R;
    L=rd();R=rd();
    out(solve(R)-solve(L-1));
    return 0;
}

转载于:https://www.cnblogs.com/ghostcai/p/9815344.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值