HDU——2089 不要62
不要62
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 54005 Accepted Submission(s): 20682
杭州交通管理局經常會擴充一些的士車牌照,新近出來一個好消息,以後上牌照,不再含有不吉利的數字了,這樣一來,就可以消除個別的士司機和乘客的心理障礙,更安全地服務大眾。
不吉利的數字為所有含有4或62的號碼。例如:
62315 73418 88914
都屬於不吉利號碼。但是,61152雖然含有6和2,但不是62連號,所以不屬於不吉利數字之列。
你的任務是,對於每次給出的一個牌照區間號,推斷出交管局今次又要實際上給多少輛新的士車上牌照了。 Input 輸入的都是整數對n、m(0<n≤m<1000000),如果遇到都是0的整數對,則輸入結束。 Output 對於每個整數對,輸出一個不含有不吉利數字的統計個數,該數值占一行位置。 Sample Input 1 100 0 0 Sample Output 80
Solution:
話說講了兩星期的數位$DP$了,入坑已久,一直沒去填坑(~妄想著打表出奇跡~
今天高三二模,學長學姐高考前最後一次模考了,雖然有點喊口號,但我還是想說“高三加油!麓山必勝!”。然後心血來潮,早上$6:30$跑到機房剛數據結構(然而沒剛出),忽覺有坑沒填,於是打了打數位板子題。
數位$DP$,其實並不難(思路好簡單啊),我們只是換個姿態在打暴力,但套上了記憶化使其大大優化而已。
普通的模擬水分,一般就是在一段範圍內枚舉每個數,將其每位拆開,然後判斷是否符合條件,計數就$OK$了(但是這樣顯然沒啥規律可循,狀態無法確定,難以記憶化)。
於是我們換個方式,首先可以利用差分的思想,區間$[l,r]$中滿足條件的數的個數$=$區間$[0,r]$滿足條件的個數$-$區間$[0,l-1]$中滿足條件的個數(這很顯然)。然後我們考慮從高位往低位枚舉$0-9$判斷是否可行,當數位到了$0$位時說明可行,那麽對於$[0,n]$這個區間,每一位都會有個限制$limit$(不能完全枚舉$0-9$中的每一個數)。舉個栗子:$n=345$,枚舉百位時顯然只能從$0-3$中選,然後當百位為$3$時枚舉十位就只能從$0-4$中選(百位為$0,1,2$時,十位就可以從$0-9$枚舉啦)。
粗略的講下思路,我們定義狀態$f[i][j],i\in[0,8],j=0/1$,表示到了第$i$位,前一位為$j$的方案數($j=0$表示前一位不為$6$,$j=1$表示前一位不為$6$,狀態視題目而定,盡量保證正確性下簡化!),那麽對於所有不受限制的情況都記錄狀態,事實證明優化賊快~。
代碼:
1 #include<bits/stdc++.h> 2 #define il inline 3 #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++) 4 using namespace std; 5 int f[20][3],cnt,n,m,ans,p[20]; 6 il int dfs(int pos,int lst,int sta,int limit){ 7 if(!pos)return 1; 8 if(!limit&&f[pos][sta]!=-1)return f[pos][sta]; 9 int up=limit?p[pos]:9,tmp=0; 10 For(i,0,up) 11 if((lst==6&&i==2)||i==4)continue; 12 else tmp+=dfs(pos-1,i,i==6,limit&&i==p[pos]); 13 if(!limit)f[pos][sta]=tmp; 14 return tmp; 15 } 16 il int solve(int x){ 17 cnt=0; 18 while(x){ 19 p[++cnt]=x%10; 20 x=x/10; 21 } 22 return dfs(cnt,-1,0,1); 23 } 24 il int gi(){ 25 int a=0;char x=getchar(); 26 while(x<‘0‘||x>‘9‘)x=getchar(); 27 while(x>=‘0‘&&x<=‘9‘)a=(a<<3)+(a<<1)+x-48,x=getchar(); 28 return a; 29 } 30 int main(){ 31 while(1){ 32 n=gi(),m=gi(); 33 if(!n&&!m)return 0; 34 memset(f,-1,sizeof(f)); 35 printf("%d\n",solve(m)-solve(n-1)); 36 } 37 return 0; 38 }
HDU——2089 不要62