hdu_2089 不要62
生活随笔
收集整理的這篇文章主要介紹了
hdu_2089 不要62
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
數位動態規劃?
????數位動態規劃是求解一個大區間[L, R]中間滿足條件Q的所有數字的個數(或者和,或其他)的一種方法。它通過分析每一位上的數字,一般用 dp[len][digit][...] 來表示狀態“len位長的數字,最高位數字為digit所具有的xx特性”,利用記憶化搜索保存中間結果,從而加快求解速度。?
????通過求 f(n) 從0到n中滿足條件Q的數字的個數,則所求的結果為 f(R) - f(L-1).?
????大多數數位dp都可以用一個DFS函數來進行記憶化搜索:
?
題目大意?
????給定一個區間[L, R],求區間內滿足條件“數位上不含有4,且不含有62(62必須連續)”的數字的個數。
分析?
????直接套用模板
實現
#include<iostream> #include<stdio.h> using namespace std; int dp[9][10]; int bits[8];//用dfs進行記憶化搜索, dp[len][digit] 表示 len位數字,最高位為digit滿足條件的個數. 這里對數字范圍沒有限制! //搜索的時候,若要進行記憶化,需要 dp[len][digit]的結果對數字范圍沒有限制,因此需要判斷 end_flag來決定是否進行記憶。//len數字的位數,digit最高位的值,end_flag 表示digit是否是第len位(從低位向高位數,個位為第1位) 的范圍邊界 int Dfs(int len, int digit, bool end_flag){//超出邊界if (len <= 0 || digit > 9 || digit < 0)return 0;//記憶化搜索,如果之前已經求出來了,則返回。注意這里要求 end_flag為falseif (!end_flag && dp[len][digit] != -1)return dp[len][digit];// 最簡單情況看數字是否滿足要求if (len == 1)return dp[len][digit] = (digit != 4);if (digit == 4)return dp[len][digit] = 0;//如果當前位是邊界數字N對應位的最大值,則下一位的范圍只能從0到邊界數字N的下一位的最大值。否則為0 到 9int end = end_flag ? bits[len - 2] : 9; int ans = 0;for (int i = 0; i <= end; i++){if (!(digit == 6 && i == 2)) //除去 62連續的情況ans += Dfs(len - 1, i, end_flag && (i==end));}if (!end_flag) //digit不是第len位的最高范圍,則可以將結果緩存dp[len][digit] = ans;return ans; }//將數字n的各個位上的范圍求出來,保存到bits數組中,返回數字n的長度 int Init(int n){ memset(bits, 0, sizeof(bits));int k = 0;while (n){bits[k++] = n % 10;n /= 10;}return k; }int Solve(int n){ int len = Init(n); //數字長度為len,則為了避免首位遍歷從0到bits[len-1],給數字增加一個前導0。//len + 1位,首位為0,且0是最高位的邊界int ans = Dfs(len + 1, 0, true);return ans; } int main(){int m, n;memset(dp, -1, sizeof(dp));while (scanf("%d %d", &m, &n)){if (m == 0 && n == 0)break; int ret1 = Solve(m-1);int ret2 = Solve(n);int ret = ret2 - ret1;printf("%d\n", ret);}return 0; }?
轉載于:https://www.cnblogs.com/gtarcoder/p/5463451.html
總結
以上是生活随笔為你收集整理的hdu_2089 不要62的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win7便笺重启计算机后还有吗,win7
- 下一篇: 音视频同步系列文章之------时间戳与