acwing 1083 Windy数

题面

acwing 1083 Windy数_第1张图片

题解(数位DP)

acwing 1083 Windy数_第2张图片

代码

#include
#include
#include
#include
#include
#include

using namespace std;
const int N = 11;

int f[N][N];   //i位数且最高位是j的Windy数

void init() {
    for (int i = 0; i <= 9; i++) f[1][i] = 1;
    for (int i = 2; i < N; i++) {  //枚举位数
        for (int j = 0; j <= 9; j++) {  //枚举最高位
            for (int k = 0; k <= 9; k++) {  //枚举次高位
                if (abs(j - k) >= 2) {
                    f[i][j] += f[i - 1][k];
                }
            }
        }
    }
}

int dp(int n) {
    if (!n) return 0;
    vector<int> nums;
    while (n) nums.push_back(n % 10), n /= 10;
    int last = -2;  //表示上一位是几
    int res = 0;

    //枚举是l位的
    for (int i = nums.size() - 1; i >= 0; i--) {
        int x = nums[i];
        for (int j = i == nums.size() - 1; j < x; j++) {  //左分支
            if (abs(j - last) >= 2) {
                res += f[i + 1][j];
            }
        }
        //右分支
        if (abs(x - last) >= 2) last = x;
        else break;

        if (!i) res++;
    }


    //不是l位的
    for (int i = 1; i < nums.size(); i++) {  //枚举位数
        for (int j = 1; j <= 9; j++) {  //枚举最高位
            res += f[i][j];
        }
    }

    return res;
}

int main() {

    init();
    int l, r;
    cin >> l >> r;
    cout << dp(r) - dp(l - 1) << endl;

    return 0;
}

你可能感兴趣的:(#,数位DP,数位DP)