码迷,mamicode.com
首页 > Windows程序 > 详细

loj10165. 「一本通 5.3 例 3」Windy 数

时间:2018-08-17 22:18:57      阅读:223      评论:0      收藏:0      [点我收藏+]

标签:ace   space   长度   max   mes   clu   --   color   ret   

思路:
  数位dp,设f[i][j]为以i为首元素, 长度为j, 的合题方案种数。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;
const int maxn = 40;
long long f[maxn][maxn];
long long ppow10[maxn];
long long getws(long long x){
    for(int i = 18; i >= 0; --i){
        if(x >= ppow10[i])
            return i + 1;
    }
    return 1;
}
long long getxk(long long x, long long k){
    if(k > getws(x))    return 0;
    return (x / ppow10[k - 1]) % 10;
}
void init(){
    ppow10[0] = 1;
    for(long long i=1; i<=20; ++i)
        ppow10[i] = ppow10[i - 1] * 10;    
    for(int i=0; i<10; ++i)
        f[i][1] = 1;        
    for(long long j=2; j<=11; ++j)
        for(long long i=0; i<10; ++i)
            for(long long k = 0; k<10; ++k)
                if(k <= i - 2 || k >= i + 2)
                    f[i][j] += f[k][j-1];
}
long long DP(long long x, long long ws){
    long long ans = 0;
    for(long long i = 1; i < ws; ++i)
        for(long long j = 1; j < 10; ++j)
            ans += f[j][i];    
    for(long long i = 1; i < getxk(x, ws); ++i)
        ans += f[i][ws];            
    for(long long i = ws - 1; i >= 1; --i){
        for(long long j = 0; j < getxk(x, i); ++j)
            if(j <= getxk(x, i + 1) - 2 || j >= getxk(x, i + 1) + 2)
                ans += f[j][i];
        if(getxk(x, i) > getxk(x, i + 1) - 2 && getxk(x, i) < getxk(x, i + 1) + 2)
            return ans;        
    }
    return ans;        
}
int main(void)
{
    init();
    long long a, b;
    cin >> a >> b;
    cout << DP(b + 1, getws(b + 1)) - DP(a, getws(a)) << endl;
}

 

loj10165. 「一本通 5.3 例 3」Windy 数

标签:ace   space   长度   max   mes   clu   --   color   ret   

原文地址:https://www.cnblogs.com/junk-yao-blog/p/9495374.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!