BZOJ1026: [SCOI2009]windy數 數位dp模板

f[i][j]表示當前有i位 第i位數字是j的合法windy數有幾種
統計1~x的答案時先考慮位數比x少的,然後枚舉1~{x的某一位-1} 加入答案
注意個位上的數要加1 不然取不到閉區間

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
#define ll long long
int f[12][10], A, B;
int stk[12], top;
ll g(int x){
    ll ans = 0, t = x;
    top = 0;
    while (t) {
        stk[++top] = t % 10;
        t /= 10;
    }
    for (int i = 1; i < top; i++)
        for (int j = 1; j <= 9; j++)    
            ans += f[i][j];
    for (int i = 1; i < stk[top]; i++) ans += f[top][i];
    stk[1]++;
    for (int i = top - 1; i >= 1; i--) {
        for (int j = 0; j < stk[i]; j++) {    //個位可以取到等
            if (abs(stk[i + 1] - j) >= 2) {
                ans += f[i][j];
            } 
        }
        if (abs(stk[i + 1] - stk[i]) < 2) break;
    }
    return ans;
}
int main(){
    cin >> A >> B;
    for (int i = 0; i <= 9; i++) f[1][i] = 1;
    for (int i = 2; i <= 11; 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];
                }
               // puts("forf\n");
            }
        }
        //cout << "yyy" << endl;
    }
    cout << g(B) - g(A - 1) << endl;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章