2382 極難的問題 【數位dp + 二分】
阿新 • • 發佈:2018-12-15
思路:
數位dp能夠求出0到m區間內的符合某個條件的數字個數,在數位dp的條件下通過二分找出符合題意的那個數字
需要注意的是,題目的n雖然是int範圍內的,但是n代表的是符合題意數字的個數,所有實際需要找的範圍應該是大於int的,需要用longlong
#include <iostream> #include <string> #include <algorithm> #include <cmath> #include <cstdio> #include <cstring> using namespace std; typedef long long ll; ll DIG[20], dp[15][15][5]; ll dfs (int cur, int last, int status, bool limit) { if (cur < 1) return status; if (!limit && dp[cur][last][status] != -1) return dp[cur][last][status]; int End = limit ? DIG[cur] : 9; ll ret = 0; for (int i = 0; i <= End; ++i) ret += dfs (cur-1, i, status && (i != 4 && i != 7), limit && (i == End)); if (!limit) dp[cur][last][status] = ret; return ret; } ll solve (ll x) { int m = 0; while (x) { DIG[++m] = x % 10; x /= 10; } return dfs (m, -1, 1, true)-1; } int main (void) { int t, n; scanf ("%d", &t); while (t--) { scanf ("%d", &n); memset (dp, -1, sizeof (dp)); ll ans = 0, L = 0, R = 10000000000, mid; while (L < R) { mid = L+(R-L)/2; if (solve (mid) >= n) R = mid; else L = mid+1; } printf ("%lld\n", R); } return 0; }