HDU 4734 F(x) (數位DP)
阿新 • • 發佈:2018-11-08
#include <iostream> #include <cstring> #include <algorithm> #include <cstdio> using namespace std; int A, B; //dp[pos][num]: 列舉到當前pos位,後面還需要湊num的權值和的個數 //也就是說初始的是時候num是f(a), 列舉一位就減去這一位在計算f(i)的權值, //那麼最後列舉完所有位 num>=0時就是滿足的,後面的位數湊足num位就可以了。 int dp[20][200000]; int bit[20]; int dfs(int pos, int num, int limit) { if (pos == -1) return num >= 0; if (num < 0)//提前結束,不必再枚舉了,優化 return 0; if (!limit && dp[pos][num] != -1) return dp[pos][num]; int ans = 0; int up = limit ? bit[pos] : 9; for (int i = 0; i <= up; i++) ans += dfs(pos-1, num-i*(1<<pos), limit && i == bit[pos]); if (!limit) dp[pos][num] = ans; return ans; } int F(int x) { int tmp = 0; int len = 0; while (x) { tmp += (x%10)*(1<<len); len++; x /= 10; } return tmp; } int cal() { int len = 0; while (B) { bit[len++] = B%10; B /= 10; } return dfs(len-1, F(A), 1); } int main() { freopen("data.in", "r", stdin); int t; int cas = 1; scanf("%d", &t); memset(dp, -1, sizeof(dp)); while (t--) { scanf("%d%d", &A, &B); printf("Case #%d: %d\n", cas++, cal()); } return 0; }