计蒜客 T2657 windy数

题目链接:计蒜客 T2657 windy数

题目大意:

题解:
数位\(dp\)题。
\(dp[pos][pre]\)表示位数为\(pos\)且第\(pos + 1\)位为\(pre\)的满足条件的数的个数,若第\(pos+1\)位为前导\(0\),则\(pre\)\(-1\)
从高位开始记忆化搜索。

#include <cmath>
#include <iostream>
using namespace std;

int dp[15][15], digit[15], l, r;

int dfs(int pos, int pre, bool limit) {
    if (!pos) {
        return pre != -1;
    }
    if (!limit && ~pre && dp[pos][pre]) {
        return dp[pos][pre];
    }
    int res = 0;
    for (int i = limit ? digit[pos] : 9; i >= 0; --i) {
        if (~pre && abs(pre - i) >= 2) {
            res += dfs(pos - 1, i, limit && i == digit[pos]);
        } else if (!~pre) {
            res += dfs(pos - 1, i ? i : -1, limit && i == digit[pos]);
        }
    }
    if (!limit && ~pre) {
        dp[pos][pre] = res;
    }
    return res;
}

int cal(int x) {
    int cnt = 0;
    while (x) {
        digit[++cnt] = x % 10;
        x /= 10;
    }
    return cnt;
}

int main() {
    cin >> l >> r;
    cout << dfs(cal(r), -1, 1) - dfs(cal(l - 1), -1, 1) << endl;
    return 0;
}
posted @ 2021-07-26 04:19  ZZHHOOUU  阅读(20)  评论(0编辑  收藏  举报