洛谷P2657 [SCOI2009]windy数

P2657 [SCOI2009]windy数

数位dp模板题,这里要考虑到前导0的情况,考虑一下就行了。
代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 55;
ll bit[N] ;
ll a, b ;
int tot;
ll dp[N][2][10][2] ;
ll ok(ll x, ll y) {
    return abs(x - y) >= 2 ;
}
ll dfs(int len, int lim, int last, int lead) {
    if(len == 0) return 1;
    if(!lim && dp[len][lim][last][lead]) return dp[len][lim][last][lead] ;
    ll ans = 0;
    int up = lim ? bit[len] : 9 ;
    if(lead && len != tot) up = 9;
    for(int i = 0; i <= up; i++) {
        if(lead || ok(last, i)) ans += dfs(len - 1, lim & (up == i), i, lead & (i == 0)) ;
    }
    return dp[len][lim][last][lead] = ans ;
}
ll solve(ll x) {
    tot = 0;
    while(x) {
        bit[++tot] = x % 10;
        x /= 10;
    }
    return dfs(tot, 1, 20, 1) ;
}
int main() {
    cin >> a >> b;
    cout << solve(b) - solve(a - 1);
    return 0;
}

posted @ 2019-05-16 19:40  heyuhhh  阅读(126)  评论(0编辑  收藏  举报