Luogu-2657 [SCOI2009]windy數
阿新 • • 發佈:2018-11-07
很少做數位\(dp\)的題,做道題學習一下吧。
記憶化搜尋,\(f[10][10][2][2]\)分別記錄當前位置,上一位數,是否有前導零和是否有大小上限。
題目要滿足相鄰兩個數相差不小於2,如果有前導零就可以無視這個限制,如果沒有就要先判斷一下。
#include<map> #include<queue> #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int f[10][10][2][2],c[10],num,a,b; int dfs(int wei,int last,int qdl,int xz){ if(wei==0) return 1; if(f[wei][last][qdl][xz]) return f[wei][last][qdl][xz]; int lim=xz?c[wei]:9,&tot=f[wei][last][qdl][xz]; for(int i=0;i<=lim;i++){ if(!qdl&&abs(last-i)<2) continue; tot+=dfs(wei-1,i,qdl&&!i,xz&&i==lim); } return tot; } inline int work(int x){ num=0; memset(f,0,sizeof(f)); while(x){ c[++num]=x%10; x/=10; } return dfs(num,0,1,1); } int main(){ //freopen(".in","r",stdin); //freopen(".out","w",stdout); scanf("%d%d",&a,&b); printf("%d\n",work(b)-work(a-1)); return 0; }