loj10164. 「一本通 5.3 例 2」数字游戏

Posted junk-yao-blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了loj10164. 「一本通 5.3 例 2」数字游戏相关的知识,希望对你有一定的参考价值。

思路:
  既然是数位dp,先写两个函数分别求一个十进制数值的指定位和该数的位数。

  设f[i][j]为用i个数字单调不降地填满j个位置,初始化f[i][0]=1(i从1到10),转移方程f[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 0;
}
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(long long i=1; i<=10; ++i)
        f[i][0] = 1;
    for(long long j=1; j<=32; ++j)
        for(long long i=1; i<=10; ++i)
            for(long long k = 1; k<=i; ++k)
                f[i][j] += f[k][j-1];
}
long long DP(long long x, long long ws){
    long long ans = 0;
    for(long long i = ws; i >= 1; --i){
        for(long long j = getxk(x, i + 1); j < getxk(x, i); ++j)
            ans += f[10 - j][i - 1];
        if(getxk(x, i) < getxk(x, i + 1))
            return ans;
    }    
    if(getxk(x, 1) >= getxk(x, 2))
        ans++;
    return ans;        
}
int main(void)
{
    init();
    long long a, b;
    while(cin >> a >> b){
        cout << DP(b, getws(b)) - DP(a - 1, getws(a - 1))<< endl;
    }
}

 


以上是关于loj10164. 「一本通 5.3 例 2」数字游戏的主要内容,如果未能解决你的问题,请参考以下文章

「一本通 4.2 例 2」最敏捷的机器人(loj10120)

loj10043. 「一本通 2.2 例 1」剪花布条

AcWing 352/loj 10131. 「一本通 4.4 例 2」暗的连锁

loj10147. 「一本通 5.1 例 1」石子合并

loj10143. 「一本通 4.6 例 1」营业额统计

loj10193. 「一本通 6.1 例 1」序列的第 k 个数