bzoj 1026: [SCOI2009]windy数【数位dp】
忘记limit不能记WA了一发……
典型数位dp,变成work(r)-work(l-1),然后dfs的时候记录w当前位置,la上一个数选的什么,lm当前位是否有上限,ok当前位是否可以不考虑差大于等于2的情况(前面全是0)
然后对于lm和ok都为0的情况记忆化一下即可
啊bzoj不知道为啥给cmath下的abs判CE……换成algorithm就没事
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=15;
long long l,r,f[N][N],a[N],tot;
long long dfs(int w,int la,int lm,int ok)
{
if(!lm&&!ok&&f[w][la])
return f[w][la];
if(!w)
return 1;
long long r=0;
if(lm)
{
for(int i=0;i<=a[w];i++)
if(abs(la-i)>1||ok)
r+=dfs(w-1,i,i==a[w],ok&&i==0);
}
else
{
for(int i=0;i<=9;i++)
if(abs(la-i)>1||ok)
r+=dfs(w-1,i,0,ok&&i==0);
}
if(!lm&&!ok)
return f[w][la]=r;
else
return r;
}
long long wk(long long x)
{
tot=0;
while(x)
a[++tot]=x%10,x/=10;
return dfs(tot,13,1,1);
}
int main()
{
scanf("%lld%lld",&l,&r);
printf("%lld\n",wk(r)-wk(l-1));
return 0;
}