2018.09.29【BZOJ1026】【洛谷P2657】【SCOI2009】windy數(數位DP)
阿新 • • 發佈:2019-01-05
洛谷傳送門
解析:
由於資料範圍很小(相對於大部分數位題來說)。
我們只記錄當前位,當前位數字,是否是前導0,是否達到上界。
簡單DP記憶化搜尋一下就好了。
程式碼:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
inline
int getint(){
re int num;
re int c;
while(!isdigit(c= gc()));num=c^48;
while(isdigit(c=gc()))num=(num<<1)+(num<<3)+(c^48);
return num;
}
int len,mark[12];
int f[12][10][2][2];
inline
int dp(int pos,int num,bool pre0,bool limit){
if(pos>len)return 1;
if(~f[pos][num][pre0][limit])return f[pos][num][pre0][limit];
int res=0;
int r;
if(limit) r=mark[pos];
else r=9;
for(int re i=0;i<=r;++i){
if(pre0||abs(i-num)>=2)
res+=dp(pos+1,i,pre0&&i==0,limit&&i==r);
}
return f[pos][num][pre0][limit]=res;
}
inline
int solve(int a){
memset(f,-1,sizeof f);
len=0;
do{
mark[++len]=a-a/10*10;
a/=10;
}while(a);
reverse(mark+1,mark+ len+1);
return dp(1,0,1,1);
}
signed main(){
int l=getint(),r=getint();
cout<<(solve(r)-solve(l-1));
return 0;
}