51nod-1009-数位dp

一时失言乱红尘 2022-07-15 14:10 283阅读 0赞

题目链接:51nod1009

1009 数字1的数量 ok.png

基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题

star.png 收藏

plus.png 关注

给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数。

例如:n = 12,包含了5个1。1,10,12共包含3个1,11包含2个1,总共5个1。

Input

  1. 输入N(1 <= N <= 10^9)

Output

  1. 输出包含1的个数

Input示例

  1. 12

Output示例

  1. 5

题目意思:给你一个数n求1-n中所有1的个数,,具体见题目描述

题目思路: (第一次写数位dp,,之前看过别人怎么写,这次自己总算是写出来了,,,好菜啊) dp [i] [j] 表示从1到以j开头的 i 位数的1的个数 例如 dp [2][2] 就表示 1 - 29的1的个数 dp [5][2] 就表示1-29999 的1的个数 ,,,那么不难推出转移方程为 dp [i] [j] = dp [i] [j-1] + dp [i-1] [9] ,,,当j=1 时 dp [i] [j] 要加上 10^(i-1)

还有就是 dp [i] [0] = dp [i-1][9]+1; 这个方程可以自己去模拟模拟,还是不难得出的,,,最后求得时候就是按位来求,,把n拆分成 1位的数 + 2位的数+ ….+n的位数的数

然后就是把没位的答案加起来,,,例如 1234 拆分成 1000 + 200 + 30 +4 所以就等于dp [1][3] +dp [2] [2] +(dp [4] [0] +n-1000) (这里是开头为1的话就要加上后面位数的数)

AC代码:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. using namespace std;
  5. int dp[10][10];
  6. void init()
  7. {
  8. memset(dp,0,sizeof(dp));
  9. int num=1;
  10. for(int i=1; i<=9; i++)
  11. {
  12. dp[i][0]=dp[i-1][9]+1; //处理以0开头
  13. for(int j=1; j<=9; j++)
  14. {
  15. dp[i][j]=dp[i][j-1]+dp[i-1][9]; //转移方程
  16. if(j==1)
  17. {
  18. dp[i][j]+=num-1; //以1开头的数
  19. }
  20. }
  21. num*=10;
  22. }
  23. }
  24. int main()
  25. {
  26. init();
  27. int n;cin>>n;
  28. int num=0; //记录位数
  29. int m=n;
  30. while(m) //统计位数
  31. {
  32. num++;
  33. m/=10;
  34. }
  35. m=1;
  36. int ans=0;
  37. for(int i=1; i<num; i++)
  38. m*=10;
  39. while(num)
  40. {
  41. int x=n/m;
  42. if(x)
  43. {
  44. ans+=dp[num][x-1]; //每个位数的答案相加
  45. if(x==1)
  46. {
  47. ans+=(n-x*m); //以1开头的情况
  48. }
  49. }
  50. num--;
  51. n-=(m*x); //得到下一位数
  52. m/=10;
  53. }
  54. cout<<ans<<endl;
  55. return 0;
  56. }

发表评论

表情:
评论列表 (有 0 条评论,283人围观)

还没有评论,来说两句吧...

相关阅读

    相关 51nod 1021石子归并 dp

    N堆石子摆成一条线。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价。计算将N堆石子合并成一堆的最小代价。

    相关 51nod1021石子归并(区间dp

    题意:N堆石子摆成一条线。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价。计算将N堆石子合并成一堆的最小代价。