求解1-n中数位递增的数

一个正整数如果任何一个数位不大于右边相邻的数位,则称为
一个数位递增的数,例如 1135 是一个数位递增的数,而 1024 不是一个数位递增
的数。给定正整数 n,请问在整数 1 至 n 中有多少个数位递增的数?
【输入格式】输入的第一行包含一个整数 n。
【输出格式】输出一行包含一个整数,表示答案。
【样例输入】30
【样例输出】26

python写吗 找我吧

n = int(input())
dp = [[0] * 10 for _ in range(10)]
for i in range(10):
    dp[1][i] = 1
for i in range(2, n+1):
    for j in range(10):
        for k in range(j):
            dp[i][j] += dp[i-1][k]
res = sum(dp[n])
print(res)

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:

这道题可以使用动态规划的思想进行求解,具体来说,对于每一位上的数,可以考虑它之前的数位中选出若干位,使得这些数位中的数字都小于等于这一位上的数字,然后将这些数位按照从小到大的顺序排列,就可以得到一个数位递增的数。

设 $dp[i][j]$ 表示考虑到第 $i$ 位,最高位为 $j$ 的数位递增的数的个数,则有:

$$
dp[i][j]=\sum_{k=0}^{j}dp[i-1][k]
$$

其中,$k$ 表示之前的数位中选出的数,其范围为 $0\sim j$,因为这些数必须小于等于当前位上的数。初始状态为 $dp[1][1]=1$,因为只有一个数位时,任何数字都是数位递增的数。

最终的答案即为 $dp[n][0]+\cdots+dp[n][9]$,即考虑到第 $n$ 位,且最高位可以是 $0$ 到 $9$ 的数位递增的数的总个数。

以下是一种 Python 的实现方式:

n = int(input())
dp = [[0] * 10 for _ in range(n+1)]
for i in range(10):
    dp[1][i] = 1
for i in range(2, n+1):
    for j in range(10):
        dp[i][j] = sum(dp[i-1][:j+1])
ans = sum(dp[n])
print(ans)

在这个程序中,我们首先读入正整数 $n$,然后定义一个 $dp$ 数组来存储状态。在计算 $dp$ 数组时,我们需要用两个循环遍历所有的状态,对于每个状态,根据状态转移方程计算出它的值。最后,输出所有数位递增的数的个数。


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7630391
  • 你也可以参考下这篇文章:百鸡问题扩展-N鸡问题N元钱买N只鸡,公鸡每只5元,母鸡每只3元,小鸡1元3只,N元钱必须刚好买N只鸡,而且鸡必须整只买,不能劈开买。 有几种买法呢?这就是N鸡问题。
  • 除此之外, 这篇博客: 蓝桥杯练习题库中的 给定正整数 n,请问在整数 1 至 n 中有多少个数位递增的数? 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • /***
    一个正整数如果任何一个数位不大于右边相邻的数位,则称为一个数位递增的数,
    例如1135是一个数位递增的数,而1024不是一个数位递增的数。
    给定正整数 n,请问在整数 1 至 n 中有多少个数位递增的数?
    ***/
    #include<stdio.h>
    int main(){
    	long int n;
    	scanf("%ld",&n);
    	int a,b,c,d,e,f; // 根据n的评测范围,定义6个长整型变量 
    	int i,count=0;
    	for(i=1;i<=n;i++){
    		if(i<10){//1到9肯定都符合,但不能因此省略,否侧测试数据小于9就出错了 
    			continue;
    		}
    		if(i>=10&&i<100){//2位数
    			a=i/10;//十位
    			b=i%10;//个位
    			if(a<=b){
    				count++;
    				continue;//该数符合条件后则返回进行下一个数的判断 
    			} 
    		}
    		if(i>=100&&i<1000)//3位数,以下思路同上 
    		{
    			a=i/100;
    			b=i/10%10;
    			c=i%10;
    			if(a<=b&&b<=c)
    			{
    				count++;
    				continue;
    			}
    		}
    		if(i>=1000&&i<10000)//4位数 
    		{
    			a=i/1000;
    			b=i/100%10;
    			c=i/10%10;
    			d=i%10;
    			if(a<=b&&b<=c&&c<=d)
    			{
    				count++;
    				continue;
    			}
    		}
    		if(i>=10000&&i<100000)//5位数 
    		{
    			a=i/10000;
    			b=i/1000%10;
    			c=i/100%10;
    			d=i/10%10;
    			e=i%10;
    			if(a<=b&&b<=c&&c<=d&&d<=e)
    			{
    				count++;
    				continue;
    			}
    		}
    		if(i>=100000&&i<1000000)//6位数 
    		{
    			a=i/100000;
    			b=i/10000%10;
    			c=i/1000%10;
    			d=i/100%10;
    			e=i/10%10;
    			f=i%10;
    			if(a<=b&&b<=c&&c<=d&&d<=e)
    			{
    				count++;
    				continue;
    			}
    		}
    	}
    	printf("%ld",count);
    	return 0;
    } 
    
    
  • 以下回答由chatgpt基于相关博客总结生成:

    求解1到n中有多少个数位递增的数。数位递增是指从左到右各个数位的数字单调不降。例如1135是一个数位递增的数,而1024不是。请问在整数1到n中有多少个数位递增的数?

    输入格式:   一个正整数n 输出格式:   一个整数,表示数位递增的数据量

    样例输入 15 样例输出 35

    代码实现如下:

    # 定义一个数位递增的函数
    def isIncrese(num):
        last_digit = 10  # 上一位放在十位表示tens,所以初始值设为10,初次循环则变成 num%10
        while num:
            if num % 10 > last_digit % 10:
                last_digit = num  # 记录上一位
                num //= 10  # 进行下一位比较
            else:
                return False
        return True
    
    n = int(input())
    ans = 0
    for i in range(1, n + 1):
        if isIncrese(i):
            ans += 1
    print(ans)
    

    其中isIncrese(num)函数用于判断一个数是否为数位递增数。循环结构中,依次遍历1到n内的每一个数字,判断其数位是否递增,如果是,则数位递增数据量加一。最后输出数位递增数据量即可。