[bzoj1026] [SCOI2009]windy数
Description
windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道,在A和B之间,包括A和B,总共有多少个windy数?
Input
包含两个整数,A B。
Output
一个整数
Sample Input
25 50
Sample Output
20
Solution
数位\(dp\)入门题。
\(f[i][j]\)表示\(i\)位,最高为是\(j\)的方案数。
然后贴着上界算答案就好了。
#include<bits/stdc++.h>
using namespace std;
void read(int &x) {
x=0;int f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}
#define write(x) printf("%d\n",x)
const int maxn = 2e5+10;
int f[30][12],r[30];
int calc(int n) {
int d=0,x=n,ans=0;
while(x) r[++d]=x%10,x/=10;
for(int i=1;i<d;i++)
for(int j=1;j<=9;j++) ans+=f[i][j];
for(int i=1;i<r[d];i++) ans+=f[d][i];
for(int i=d-1;i;i--) {
for(int j=0;j<r[i];j++) if(abs(j-r[i+1])>=2) ans+=f[i][j];
if(abs(r[i+1]-r[i])<2) break;
if(i==1) ans++;
}return ans;
}
int main() {
for(int i=0;i<=9;i++) f[1][i]=1;
for(int i=2;i<=15;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 a,b;read(a),read(b),write(calc(b)-calc(a-1));
return 0;
}