bzoj1026 [SCOI2009]windy数

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1026

【题解】

基本数位dp。

写了半天发现自己太傻了。。。

# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 5e5 + 10;
const int mod = 1e9+7;


int A, B;
int f[20][10];
int w[12], wn = 0;

inline int abs(int x) {
    return x>0 ? x : -x;
}

inline int solve(int n) {
    if(n == 0) return 0;
    wn = 0; int t = n;
    while(t) w[++wn] = t%10, t/=10;
    int ret = 0;
    for (int i=wn-1; i; --i)
        for (int j=1; j<=9; ++j) ret += f[i][j];
    for (int i=wn, las=-1; i; --i) {
        if(i == 1) {
            for (int k=0; k<=w[i]; ++k) if(abs(w[i+1]-k) >= 2) ++ret;
        } else {
            for (int j=(i == wn ? 1 : 0); j<w[i]; ++j) 
                if(las == -1 || abs(j-las) >= 2) ret += f[i][j];
        }
        if(las == -1 || abs(las - w[i]) >= 2) las = w[i];
        else break;
    }
    return ret;
}

int main() {
    cin >> A >> B;
    for (int j=0; j<=9; ++j) f[1][j] = 1;
    for (int i=2; i<=10; ++i) 
        for (int j=0; j<=9; ++j) 
            for (int k=0; k<=9; ++k) {
                if(abs(j-k) < 2) continue;
                f[i][j] += f[i-1][k];
            }
    cout << solve(B) - solve(A-1);
    return 0;
}
View Code

 

posted @ 2017-07-05 17:07  Galaxies  阅读(161)  评论(0编辑  收藏  举报