BZOJ1026 [SCOI2009]windy数
题面在这里
数位DP写起来很简单,但是很难想啊……
发现果然还是记忆化搜索好写
定义\(dfs(step,last,less,first)\)表示处理到step位,上一位是last,是否小于给定数,是否含有前导零
然后就好了
示例程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| #include<cstdio> #include<cstring> #define _abs(x) ((x)<0?-(x):(x)) #define cl(x,y) memset(x,y,sizeof(x))
const int maxn=15; int l,r,f[maxn][maxn]; int a[maxn],len; int dfs(int stp,int lst,bool ls,bool fir){ if (stp==0) return 1; if (ls&&!fir&&f[stp][lst]!=-1) return f[stp][lst]; int now=ls?9:a[stp],res=0; for (int i=0;i<=now;i++) if (fir||_abs(i-lst)>=2) res+=dfs(stp-1,i,ls||i<a[stp],fir&&!i); return !ls||fir?res:f[stp][lst]=res; } int calc(int x){ len=0; for (;x;x/=10) a[++len]=x%10; return dfs(len,0,0,1); } int main(){ scanf("%d%d",&l,&r); cl(f,-1); printf("%d",calc(r)-calc(l-1)); return 0; }
|