HDU 2089 is not 62 (Digital DP, three positions)
ACM
Address: HDU 2089
Question:
Chinese meaning, not explained.
Analysis:
- Million data, brute-force table Creation
- Initialize the DP array, which indicates three conditions of the first I-bit before calculation.
- Direct DFS, search and change records over and over again, and there may be some hunger-and-thirst calculations and hunger-and-thirst computations. Records can only be recorded for all computations (we recommend that you refer to orz for a ∑)
Code:
1. Brute Force (previously written)
/** Author: illuz <iilluzen[at]gmail.com>* File: 2089_bf.cpp* Create Date: 2014-03-31 20:28:46* Descripton: brute force way */#include <cstdio>#define RII(x,y) scanf("%d%d",&x,&y)#define PIN(x) printf("%d\n",x)#define repf(i,a,b) for(int i=(a);i<=(b);i++)const int N = 1000010;int f[N], n, m;bool check(int r) {while (r) {if (r % 10 == 4) return false;if (r % 100 == 62) return false;r /= 10;}return true;}void init() {repf (i, 1, 1000000)if (check(i))f[i] = f[i - 1] + 1;elsef[i] = f[i - 1];}int main(){init();while (RII(n, m) && (n || m)) {PIN(f[m] - f[n - 1]);}return 0;}
2. dp_1
/** Author: illuz <iilluzen[at]gmail.com>* File: 2089.cpp* Create Date: 2014-07-26 09:55:48* Descripton: */#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define RII(x,y) scanf("%d%d",&x,&y)#define PIN(x) printf("%d\n",x)#define repf(i,a,b) for(int i=(a);i<=(b);i++)#define repd(i,a,b) for(int i=(a);i>=(b);i--)const int N = 10;int n, m;int bits[N];int dp[N][3];// [len][x]// 0->luck// 1->luck and highest is 2// 2->unluckvoid init() {dp[0][0] = 1;// len is 0 and luck is 1, becauses the dp[1][1] will equal it.dp[0][1] = dp[0][1] = 0;repf(i, 1, N - 1) {dp[i][0] = dp[i - 1][0] * 9// i-1_luck without 4- dp[i - 1][1];// and without 62dp[i][1] = dp[i - 1][0];// equal to i-1_luck_2 + '6'dp[i][2] = dp[i - 1][2] * 10// unluck is always unluck+ dp[i - 1][0]// i-1_luck + '4'+ dp[i - 1][1];// i-1_luck_2 + '6'}}int solve(int num) {int len = 0, rec = num, ans, flag;// get bits arraywhile (num) {bits[++len] = num % 10;num /= 10;}bits[len + 1] = 0;ans = 0;// the unluck numflag = 0;// if appear unluck repd (i, len, 1) {ans += dp[i - 1][2] * bits[i];// unluck is always unluckif (flag) {// if unluck appearedans += dp[i - 1][0] * bits[i];// all luck become unluck} else {if (bits[i] > 4) {ans += dp[i - 1][0];// i-1_luck + '4'}if (bits[i] > 6) {ans += dp[i - 1][1];// i-1_luck_2 + '6'}if (bits[i + 1] == 6 && bits[i] > 2) {ans += dp[i][1];}}if (bits[i] == 4 || (bits[i + 1] == 6 && bits[i] == 2)) {flag = 1;}}return rec - ans;}int main() {init();while (~RII(n, m) && (n || m)) {PIN(solve(m + 1) - solve(n));}return 0;}
3. dp_2 (DFS)
/** Author: illuz <iilluzen[at]gmail.com>* File: 2089_dfs.cpp* Create Date: 2014-07-26 15:21:12* Descripton: dfs version */#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define RII(x,y) scanf("%d%d",&x,&y)#define PIN(x) printf("%d\n",x)const int N = 10;int bits[N], dp[N][2];// dp[i][is6] is the number of i-len digits with (if prevent number is 6), its digits are from 0-9// the rest length, Is the prevent digit 6, Is the digit maxint dfs(int len, bool is6, bool ismax) {if (len == 0)return 1;if (!ismax && dp[len][is6] >= 0)// dpreturn dp[len][is6];int cnt = 0, mmax = (ismax? bits[len] : 9);for (int i = 0; i <= mmax; i++) {if (i == 4 || is6 && i == 2)// unluck digitcontinue;cnt += dfs(len - 1, i == 6, ismax && i == mmax);}return ismax ? cnt : dp[len][is6] = cnt;// remember the result}int solve(int num) {int len = 0;while (num) {bits[++len] = num % 10;num /= 10;}return dfs(len, false, true);}int main() {int n, m;memset(dp, -1, sizeof(dp));while (~scanf("%d%d", &n, &m) && (n || m)) {PIN(solve(m) - solve(n - 1));}return 0;}