今上午看了拓撲排序和關鍵路徑,瞭解了基本原理,至於代碼還只看了模版,題目還沒有多看。
今下午和晚上,複習了數位DP,有了更加深入的認識,基礎題型是計算一個區間(a,b)符合某個條件的數的個數。一般數位dp是一種暴力枚舉的方法。它就是在數位上一位一位的枚舉,使得這種枚舉方式符合dp的定義,並且使用記憶化搜索,就會節省枚舉的時間。換了一個模版,實用性更大,但是不怎麼好理解,暫時可以理解個大概:
- int a[20];
- int dp[20][state];
- int dfs(int pos,int zhuangtai,/*這裏可能有很多狀態*/int limit)
- {
- if(pos==-1)return 1;//這裏根據情況不一樣,返回值不一樣
- if(!limit&&dp[pos][state]!=-1/*如果有前導零的題,這裏還有前導零的判斷*/)return dp[pos][state];
- int sum=0;
- int end=limit?a[pos]:9;//這裏是根據這一位數是否應該有限制,設置枚舉的最大數,不過這是十進制的
- for(int i=0;i<=end;i++)//循環
- {
- if()....//限制條件。
- sum+=dfs(pos-1,/*狀態或者前導零*/limit&&i==a[pos])
- }
- if(!limit/*有時候有前導零*/)dp[pos][state];
- return sum;
- }
- int solve(int x)
- {
- int pos=0;
- while(x)
- {
- a[pos++]=x%10;
- x/10;
- }//這裏是數位分解
- return dfs(pos-1,/*狀態限制*/,1);
- }
- int main()
- {
- int q,w;
- while(~scanf("%d%d",&q,&w))
- {
- printf("%d\n",solve(q)-solve(w));
- }
- return 0;
- }