Q: Give M, N, and ask the k Number containing M 0, which is the number of digits and the maximum number.
Idea: Add a binary point like a common digital DP.
Then pay attention to whether the limit value can be calculated under the test. The limit value is very large!
Code:
# Include "cstdlib" # include "cstdio" # include "cstring" # include "cmath" # include "queue" # include "algorithm" # include "iostream" using namespace STD; // September 24, 2014 17:07:38 _ int64 DP [22] [22] [11]; int num [22] ;__ int64 DFS (INT site, int N, int M, int zero, int f) {If (Site = 0) {If (zero) return 0; return n = m? 1:0;} If (! F &&! Zero &&~ DP [site] [N] [m]) return DP [site] [N] [m]; int Len = f? Num [site]: 9; _ int64 ans = 0; For (INT I = 0; I <= Len; I ++) {If (zero) ans + = DFS (site-1, n, m, zero & I = 0, F & I = Len); else {if (I = 0) ans + = DFS (site-1, n + 1, m, zero & I = 0, F & I = Len ); else ans + = DFS (site-1, n, m, zero & I = 0, F & I = Len) ;}} if (! F &&! Zero) DP [site] [N] [m] = ans; return ans ;}__ int64 solve (_ int64 X, int m) {If (x <0) return 0; int CNT = 0; while (x) {num [++ CNT] = x % 10; X/= 10;} return DFS (CNT, 0, m, 1, 1);} int main () {int t; CIN> T; memset (DP,-1, sizeof (DP); While (t --) {_ int64 K; int m; scanf ("% d % i64d", & M, & K); _ int64 L = 1, R = 90020.00000000ll, mid, ans; while (L <= r) {mid = (L + r)/2; If (solve (MID, m)> = k) {ans = mid; R = mid-1 ;}else L = Mid + 1 ;}_ int64 Len, TT = 1, n; Len = (_ int64) log10 (ANS * 1.0) + 1; n = len-1; while (n --) TT * = 10; printf ("% i64d % i64d \ n", Len, ANS/TT ); // printf ("% i64d \ n", ANS);} return 0;} // September 24, 2014 18:07:25
[Digital DP + binary] fzu 1074 Nancy's birthday