uva12486 Space Elevator(数位dp)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud
题意:问第n个各个数位上不出现连续的13和4的数是多少?从1开始算,n<=10^18
莫名奇妙地写跪了,重写一发就过了、、、
可以比较容易的得出小于等于x的满足那些要求的数有多少个,然后根据这个二分。直接二分答案。
注意需要用unsigned long long
/** * code generated by JHelper * More info: https://github.com/AlexeyDmitriev/JHelper * @author xyiyy @https://github.com/xyiyy */ #include <iostream> #include <fstream> //##################### //Author:fraud //Blog: http://www.cnblogs.com/fraud/ //##################### //#pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <sstream> #include <ios> #include <iomanip> #include <functional> #include <algorithm> #include <vector> #include <string> #include <list> #include <queue> #include <deque> #include <stack> #include <set> #include <map> #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <climits> #include <cctype> using namespace std; #define rep(X, N) for(int X=0;X<N;X++) #define dep(X, R, L) for(int X=R;X>=L;X--) typedef unsigned long long ull; typedef unsigned long long ull; ull dp[30][10]; int d[30]; class TaskE { public: void solve(std::istream &in, std::ostream &out) { //bign n; rep(i, 30) rep(j, 10)dp[i][j] = 0; run(); ull n; while (in >> n) { ull ans = 1; ull l = 1; ull r = -1; while (l <= r) { int f = 0; if ((l & 1) && (r & 1))f++; ull mid = (r >> 1) + (l >> 1) + f; if (gao(mid) <= n) { ans = mid; l = mid + 1; } else { r = mid - 1; } } out << ans << endl; } } ull gao(ull n) { ull ans = 0; int len = 0; while (n) { d[++len] = n % 10; n /= 10; } d[len + 1] = 0; dep(i, len, 1) { rep(j, d[i]) { if (d[i + 1] != 1 || j != 3) { ans += dp[i][j]; } } if (d[i] == 4 || (d[i + 1] == 1 && d[i] == 3))break; } return ans; } void run() { dp[0][0] = 1; for (int i = 1; i <= 20; i++) { for (int j = 0; j <= 9; j++) { for (int k = 0; k <= 9; k++) { if (j != 4 && !(j == 1 && k == 3)) { dp[i][j] += dp[i - 1][k]; } } } } } }; int main() { std::ios::sync_with_stdio(false); std::cin.tie(0); TaskE solver; std::istream &in(std::cin); std::ostream &out(std::cout); solver.solve(in, out); return 0; }