方法:数位DP?
解析:数位DP个鬼,明明就是数位递推
首先对于这个数据范围,O(1)能过?
再想想不对,9次方最大也就是9位啊!
所以可以想到一种状态f[i][j]代表长度为i且首位为j的windy数
然后就是乱搞递推了
f[i][j]=∑f[i−1][k]且abs(k−j)>=2
之后就是细节调代码按位处理了
不过我有个问题啊喂
为什么我所有的只有一位的值算的都不对啊?别的位就对?
所以我只好无耻一点了,加特判,询问1~9直接返回自己
先挖个坑。
代码:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int f[15][15];
int bit[15];
void init()
{
for(int i=0;i<=9;i++)f[1][i]=1;
for(int i=2;i<=10;i++)
{
for(int j=0;j<=9;j++)
{
for(int k=0;k<=9;k++)
{
if(abs(j-k)>=2)f[i][j]+=f[i-1][k];
}
}
}
}
int cal(int x)
{
if(x<10)return x;
if(!x)return 0;
int s_bit=10,ans=0;
while(bit[s_bit]>x)s_bit--;
for(int i=1;i<s_bit;i++)
{
for(int j=1;j<=9;j++)
{
ans+=f[i][j];
}
}
int aft=x/bit[s_bit];
x%=bit[s_bit];
for(int i=1;i<aft;i++)ans+=f[s_bit][i];
int pre_bit=aft;
for(int i=s_bit-1;i;i--)
{
int bit_now=x/bit[i];
if(i!=1)
{
for(int j=0;j<bit_now;j++)
{
if(abs(pre_bit-j)>=2)ans+=f[i][j];
}
}else
{
for(int j=0;j<=bit_now;j++)
{
if(abs(pre_bit-j)>=2)ans+=f[i][j];
}
}
if(abs(pre_bit-bit_now)<2)break;
pre_bit=bit_now;
x%=bit[i];
}
return ans;
}
int main()
{
int a,b;
scanf("%d%d",&a,&b);
init();
bit[1]=1;
for(int i=2;i<=10;i++)bit[i]=bit[i-1]*10;
cal(1);
printf("%d\n",cal(b)-cal(a-1));
}