bzoj1026: [SCOI2009]windy数---数位dp
windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道,在A和B之间,包括A和B,总共有多少个windy数?
数位dp,前导0的情况要考虑掉,dp【i】【j】【2】开三位表示i长度,j前一位是什么,k前面是不是全是前导0
//#pragma comment(linker, "/stack:200000000") //#pragma GCC optimize("Ofast,no-stack-protector") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") //#pragma GCC optimize("unroll-loops") #include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pi acos(-1.0) #define ll long long #define mod 100003 #define C 0.5772156649 //#define ls l,m,rt<<1 //#define rs m+1,r,rt<<1|1 #define pil pair<int,ll> #define pii pair<int,int> #define cd complex<double> #define ull unsigned long long #define base 1000000000000000000 #define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-12; const int N=100+10,maxn=1200000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f; int dp[N][N][2],digit[N]; int dfs(int len,int state,bool ok,bool fp) { if(!len)return 1; if(!fp&&dp[len][state][ok]!=-1)return dp[len][state][ok]; int ret=0,fpmax=fp ? digit[len] : 9; for(int i=0;i<=fpmax;i++) { if(ok&&abs(i-state)<2)continue; ret+=dfs(len-1,i,ok|i,fp&&i==fpmax); } // printf("%d %d %d\n",len,state,ret); if(!fp)dp[len][state][ok]=ret; return ret; } int solve(int x) { int len=0; while(x) { digit[++len]=x%10; x/=10; } return dfs(len,0,0,1); } int main() { int a,b; scanf("%d%d",&a,&b); memset(dp,-1,sizeof dp); printf("%d\n",solve(b)-solve(a-1)); return 0; } /******************** ********************/