首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

HDU 3555 Bomb:數位 DP 統計包含「49」的數字個數

     編輯:關於C++

問題描述

統計 1 到 N(N ≤ 2⁶³-1)中包含子序列「49」的數字個數。多測試用例 T ≤ 10000。

數位 DP 模板

狀態:dfs(pos, pre, has49, limit)

  • pos:當前處理位置(從高位到低位)
  • pre:前一位數字
  • has49:是否已出現「49」
  • limit:是否受 N 的對應位限制

狀態轉移

ll dfs(int pos, int pre, bool has49, bool limit) {
    if (pos == -1) return has49;  // 到達最低位,若已含49計1
    if (!limit && dp[pos][pre][has49] != -1) return dp[pos][pre][has49];
    
    int up = limit ? digit[pos] : 9;
    ll res = 0;
    for (int d = 0; d <= up; ++d) {
        bool nHas49 = has49 || (pre == 4 && d == 9);
        res += dfs(pos-1, d, nHas49, limit && d==up);
    }
    if (!limit) dp[pos][pre][has49] = res;
    return res;
}

完整代碼

#include 
using namespace std;
using ll = long long;

ll dp[20][10][2];
int digit[20];

ll dfs(int pos, int pre, bool has49, bool limit) {
    if (pos < 0) return has49;
    if (!limit && dp[pos][pre][has49] != -1) return dp[pos][pre][has49];
    int up = limit ? digit[pos] : 9;
    ll res = 0;
    for (int d = 0; d <= up; ++d) {
        res += dfs(pos-1, d, has49 || (pre==4 && d==9), limit && d==up);
    }
    if (!limit) dp[pos][pre][has49] = res;
    return res;
}

ll solve(ll x) {
    int len = 0;
    while (x) { digit[len++] = x % 10; x /= 10; }
    return dfs(len-1, 0, false, true);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    memset(dp, -1, sizeof(dp));
    int T; cin >> T;
    while (T--) {
        ll n; cin >> n;
        cout << solve(n) << '\n';
    }
    return 0;
}

關鍵點總結

要點說明
狀態壓縮pre 只需 0-9,has49 只有 0/1,狀態數極小
前導零處理pre 初始為 0,但最高位不能為 0(由 limit 控制),自然避免前導零干擾
記憶化只在 !limit 時記憶/查詢,limit=true 時不可複用
長長整型N ≤ 2⁶³-1,答案 ≤ N,必須用 long long / __int64

擴展:統計不包含「49」的數

總數 N 減去包含「49」的數,或修改 DP 返回 !has49。同類問題:「不要 62」(HDU 2089)、「666」(HDU 3652)等。

複雜度

  • 預處理:O(1)
  • 單次查詢:O(位數 × 狀態數) = O(19 × 10 × 2) ≈ 380 操作
  • 10000 測試用例總計 < 4×10⁶ 操作,極快
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved