编程 小数位数

Problem statement:

问题陈述:

Given the number of digits n, find the count of total non-decreasing numbers with n digits.

给定位数n ,找到具有n位数字的非递减总数。

A number is non-decreasing if every digit (except the first one) is greater than or equal to the previous digit. For example, 22,223, 45567, 899, are non-decreasing numbers whereas 321 or 322 are not.

如果每个数字(第一个数字除外)都大于或等于前一个数字,则数字不减。 例如,22,223、45567、899是不减数字,而321或322不是。

Input:

输入:

The first line of input contains an integer T denoting the number of test cases. Then T test cases follow. The first line of each test case contains the integer n.

输入的第一行包含一个整数T,表示测试用例的数量。 然后是T测试用例。 每个测试用例的第一行包含整数n

Output:

输出:

Print the count of total non-decreasing numbers with n digits for each test case in a new line. You may need to use unsigned long long int as the count can be very large.

在新行中为每个测试用例用n位数字打印非降序总数。 您可能需要使用unsigned long long int,因为计数可能非常大。

Constraints:

限制条件:

1 <= T <= 100
1 <= n <= 200

Example:

例:

Input:
No of test cases, 3
n=1
n=2
n=3
Output:
For n=1
Total count is: 10
For n=2
Total count is: 55
For n=3
Total count is: 220

Explanation:

说明:

For n=1,
The non-decreasing numbers are basically 0 to 9,
counting up to 10
For, n=2,
The non-decreasing numbers can be
00
01
02
..
11
12
13
14
15
.. so on total 55

Solution Approach:

解决方法:

The solution can be recursive. In recursion our strategy will be to build the string (read: number) such that at each recursive call the number to be appended would be necessarily bigger (or equal) than(to) the last one.

解决方案可以是递归的。 在递归中,我们的策略是构建字符串(读取:number),以便在每次递归调用时,要附加的数字必然大于(或等于)最后一个数字。

Say, at any recursion call,

说,在任何递归调用中,

The number already constructed is x1x2...xi where i<n, So at the recursive call we are allowed to append digits only which are equal to greater to xi.

已经构造的数字是x 1 x 2 ... x i ,其中i <n ,因此在递归调用中,我们只允许附加等于x i的数字

So, let's formulate the recursion

因此,让我们制定递归

Say, the recursive function is computerecur(int index, int last, int n)

说,递归函数是computerecur(int index,int last,int n)

Where,

哪里,

  • index = current position to append digit

    索引 =当前位置追加数字

  • Last = the previous digit

    最后 =前一位

  • n = number of total digits

    n =总位数

unsigned long long int computerecur (int index,int last,int n){
// base case
if(index has reached the last digit)
return 1;
unsigned long long int sum=0;
for digit to append at current index,i=0 to 9
if(i>=last)
// recur if I can be appended
sum + =computerecur(index+1,i,n);
end for
return sum
End function

So the basic idea to the recursion is that if it's a valid digit to append (depending on the last digit) then append it and recur for the remaining digits.

因此,递归的基本思想是,如果要追加的有效数字(取决于最后一位),则将其追加并针对剩余的数字进行递归。

Now the call from the main() function should be done by appending the first digit already (basically we will keep that first digit as last digit position for the recursion call).

现在,应该通过已经附加了第一个数字来完成对main()函数的调用(基本上,我们将把该第一个数字保留为递归调用的最后一个数字位置)。

So at main,

所以总的来说

We will call as,

我们称之为

unsigned long long int result=0;
for i=0 to 9 //starting digits
// index=0, starting digit assigned as
// last digit for recursion
result+=computerecur(0,i,n);
end for

The result is the ultimate result.

结果就是最终结果。

I would suggest you draw the recursion tree to have a better understanding, Take n=3 and do yourself.

我建议您绘制递归树以更好地理解,取n = 3并自己做。

For, n=2, I will brief the tree below

对于n = 2 ,我将简要介绍下面的树

For starting digit 0
Computerecur(0,0,2)
Index!=n-1
So
Goes to the loop
And then
It calls to
Computerecur(1,0,2) // it's for number 00
Computerecur(1,1,2) // it's for number 01
Computerecur(1,2,2) // it's for number 02
Computerecur(1,3,2) // it's for number 03
Computerecur(1,4,2) // it's for number 04
Computerecur(1,5,2) // it's for number 05
Computerecur(1,6,2) // it's for number 06
Computerecur(1,7,2) // it's for number 07
Computerecur(1,8,2) // it's for number 08
Computerecur(1,9,2) // it's for number 09
So on
...

Now, it's pretty easy to infer that it leads to many overlapping sub-problem and hence we need dynamic programming to store the results of overlapping sub-problems. That's why I have used the memoization technique to store the already computed sub-problem results. See the below implementation to understand the memorization part.

现在,很容易推断出它会导致许多子问题重叠,因此我们需要动态编程来存储子问题重叠的结果。 这就是为什么我使用记忆技术来存储已经计算出的子问题结果的原因。 请参阅以下实现以了解记忆部分。

C++ Implementation:

C ++实现:

#include <bits/stdc++.h>
using namespace std;
unsigned long long int dp[501][10];
unsigned long long int my(int index, int last, int n)
{
if (index == n - 1)
return 1;
// memorization, don't compute again what is already computed
if (dp[index][last] != -1)
return dp[index][last];
unsigned long long int sum = 0;
for (int i = 0; i <= 9; i++) {
if (i >= last)
sum += my(index + 1, i, n);
}
dp[index][last] = sum;
return dp[index][last];
}
unsigned long long int compute(int n)
{
unsigned long long int sum = 0;
for (int i = 0; i <= 9; i++) {
sum += my(0, i, n);
}
return sum;
}
int main()
{
int t, n, item;
cout << "enter number of testcase\n";
scanf("%d", &t);
for (int i = 0; i < t; i++) {
cout << "Enter the number of digits,n:\n";
scanf("%d", &n);
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= 9; j++) {
dp[i][j] = -1;
}
}
cout << "number of non-decreasing number with " << n;
cout << " digits are: " << compute(n) << endl;
}
return 0;
}

Output:

输出:

enter number of testcase
3
Enter the number of digits,n:
2
number of non-decreasing number with 2 digits are: 55
Enter the number of digits,n:
3
number of non-decreasing number with 3 digits are: 220
Enter the number of digits,n:
6
number of non-decreasing number with 6 digits are: 5005

翻译自: https://www.includehelp.com/icp/total-number-of-non-decreasing-numbers-with-n-digits-using-dynamic-programming.aspx

编程 小数位数

编程 小数位数_使用动态编程的n位数的非递减总数相关推荐

  1. dp 扔鸡蛋_使用动态编程(DP)的鸡蛋掉落问题

    dp 扔鸡蛋 Problem statement: You are given N floor and K eggs. You have to minimize the number of times ...

  2. 三丰三坐标编程基本步骤_数控车床编程,经典实例教程

    一.数控车编程特点 (1) 可以采用绝对值编程(用X.Z表示).增量值编程(用U.W表示)或者二者混合编程. (2) 直径方向(X方向) 系统默认为直径编程,也可以采用半径编程,但必须更改系统设定. ...

  3. java面试编程面试题_完美的编程面试问题

    java面试编程面试题 by Sachin Malhotra 由Sachin Malhotra 完美的编程面试问题 (The Perfect Programming Interview Problem ...

  4. java动态编程解决分硬币问题,动态编程硬币更改问题

    我在理解各种问题的动态编程解决方案时遇到问题,特别是硬币找零问题: "给定值N,如果我们要N分钱找零,并且我们有无限数量的S = {S1,S2,..,Sm}硬币的供应,我们可以用几种方法进行 ...

  5. 风变编程python网址_风变编程Python:如何打造职场差异化竞争优势

    吴军在<浪潮之巅>里指出,21世界最终会是人工智能的世纪,我们要么成为他们的奴隶,要么成为他们的神.每次开学我都会问学生们一个问题:如何才能比别人更优秀?更好的学历?更丰富的工作经验?事实 ...

  6. java编程思想怎么样_读完java编程思想后的思考?

    谢邀,这本书真的给我带来很多思考. 我的java入门不是java编程思想,学校的教材是一本紫色的书,已经忘了叫什么名字了,里面内容倒挺新还讲了些javafx.但那本书实在是太浅并且结构混乱,以至于我和 ...

  7. java编程基础码_【Java编程的逻辑】编程基础

    数据类型和变量 数据类型用于对数据归类,以便于理解和操做. - 整数类型:byte/short/int/long, 分别有不一样的取值范围 - 小数类型:float/double,有不一样的取值范围和 ...

  8. vb初学者编程代码大全_学习VB编程第14天,一个简单的排序代码把我难住了

    今天学习了刘金玉老师VB编程教程的第21期,学习的主要内容是冒泡排序算法. 一.算法的主要种类 1.算法的种类有冒泡排序法.选址排序法.折半查找法.快速排序法.穷举法等. 2.补充知识:variant ...

  9. 猿编程python代码_程序猿编程课堂 Python学习之入门篇3:简单的数据类型

    1. 什么是数据类型? 我们知道编程就是编写程序解决某个问题,而任何能使用编程来解决的问题都是能够提取或者转换出相应的数据,只是数据的表达形式是不一样的,而这表达形式就是数据类型. 比如,数学中的数字 ...

最新文章

  1. Matlab与随机变量和样本的数字特征
  2. 二维码检测哪家强?五大开源库测评比较
  3. 深度学习1:生成模型的输入数据集和可视化
  4. 类的属性、类的方法、类的内置方法
  5. C++ leetcode 26. 删除排序数组中的重复项 给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
  6. Android开发线程池管理类之ThreadPoolExecutor工具类
  7. ai中如何插入签名_技巧不求人167期 Excel如何打印到1页纸的2种方法 Excel如何插入手写签名...
  8. kafka key的作用_震惊了,原来这才是Kafka的“真面目”!
  9. Android UI 事件研究
  10. 3、plt.figure()和Axes类
  11. VS2010中常用的快捷键
  12. vsto java,从Excel VSTO项目打开WPF应用程序
  13. 搜狗微信文章url解码
  14. 在线社交网络的影响力最大化算法
  15. python句柄无效_使用pyinstaller打包,subprocess报“句柄无效”错误的解决方法
  16. C程序内存泄露检测工具——Valgrind
  17. elasticsearch6.5.4破解白金版xpack
  18. App 锁屏的时候显示App的内容
  19. 如何选择智能车牌识别摄像机
  20. win10下台式电脑主机,无法播放声音解决办法。

热门文章

  1. python图标icon_用Python提取exe图标icon
  2. html5 loaded,How do you check if a HTML5 audio element is loaded?
  3. react如何监听路由url变化
  4. Bootstrap定制开发
  5. 【CSS】小妙招,各种问题总结方法处理
  6. USACO 6.3 章节 你对搜索和剪枝一无所知QAQ
  7. leetcode 134. 加油站(Gas Station)
  8. KMP算法的java实现
  9. Mercurial hg web server的配置
  10. POJ 2115 C Looooops(扩展欧几里得)