http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1009

1009 数字1的数量

基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题
收藏
关注
给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数。

例如:n = 12,包含了5个1。1,10,12共包含3个1,11包含2个1,总共5个1。
Input
输入N(1 <= N <= 10^9)
Output
输出包含1的个数
Input示例
12
Output示例
5
第一次写数位dp还是挺头疼的啊,dp[i][j]表示以j开头的i位数x=(j+1)*pow(10,i-1)-1,1-x之间所有的数中1出现的次数。
不难写出方程 dp[i][j]=dp[i][j-1]+dp[i-1][9] 这个自己模拟一下就知道了,
特殊的对于 dp[i][0]=dp[i-1][9] ;
当j==1时上面的方程也要变化为 dp[i][1]=dp[i][j-1]*2+pow(10,i-1),这是因为最高位的'1'不能被忽略
之后对于每次询问的数将他依次拆解计算,
例如对于N=3456,我们先拆出来 [1,2999],也就是 dp[4][2] ,容易发现剩下的数就是 3000-3456,但是3!=1,所以这一段<==> 1-456,这样每次计算一位就ok,
特殊的对于出现1的位置例如 1234,我们加上dp[4][0]之后剩下的数是 1000-1234,这个1显然不能抛弃,我们加上234+1个'1'之后再把数转化为 1-234计算就好了。
第一次写所以写了个暴力对拍! 注意枚举低位的时候如果高位有1,统计一下所有高位的1,乘上当前区间内数的个数。
 #include<bits/stdc++.h>
using namespace std;
int f[][];
int bit[];
int p10[]={};
int cal(int N){
int ans=,len=,ok=;
while(N){
bit[len++]=N%;
N/=;
}
bit[len]=-;
for(int i=len-;i>=;--i){
for(int k=;k<bit[i];++k){
ans+=f[i+][k];
int tot=;
for(int j=i+;j<len;j++){
if(bit[j]==){
tot++;
}
}
ans+=tot*p10[i];
}
}
return ans;
}
int main(){
int i,j,k;
for(i=;i<;++i) p10[i]=p10[i-]*;
f[][]=;
for(i=;i<=;++i){
for(j=;j<;++j){
for(k=;k<;++k){
f[i][j]+=f[i-][k];
}
if(j==) f[i][j]+=p10[i-];
}
} int N;
while(scanf("%d",&N)==)
printf("%d\n",cal(N+));
return ;
}

  f[i]表示所有的i位数中包含1的个数,有前导零的数也计算在内,因为在计算高位时低位可以为零。

 #include<bits/stdc++.h>
using namespace std;
#define LL long long
LL f[]={,};
LL p10[]={,};
int bit[];
void init(){
for(int i=;i<=;++i) p10[i]=p10[i-]*;
for(int i=;i<=;++i) f[i]=f[i-]*+p10[i-];
}
LL cal(int N){
int len=;
while(N){
bit[len++]=N%;
N/=;
}
bit[len]=-;
LL ans=,one=;
for(int i=len-;i>=;--i){
ans+=f[i]*bit[i];
if(bit[i]>) ans+=p10[i];
ans+=p10[i]*bit[i]*one;
if(bit[i]==) one++;
}
return ans;
}
int main(){
int n,i,j,k;
init();
while(scanf("%d",&n)==){
printf("%lld\n",cal(n+));
}
return ;
}

51nod 1009 数位dp入门的更多相关文章

  1. xbz分组题B 吉利数字 数位dp入门

    B吉利数字时限:1s [题目描述]算卦大湿biboyouyun最近得出一个神奇的结论,如果一个数字,它的各个数位相加能够被10整除,则称它为吉利数.现在叫你计算某个区间内有多少个吉利数字. [输入]第 ...

  2. 数位dp入门 hdu2089 不要62

    数位dp入门 hdu2089 不要62 题意: 给定一个区间[n,m] (0< n ≤ m<1000000),找出不含4和'62'的数的个数 (ps:开始以为直接暴力可以..貌似可以,但是 ...

  3. hdu3555 Bomb 数位DP入门

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555 简单的数位DP入门题目 思路和hdu2089基本一样 直接贴代码了,代码里有详细的注释 代码: ...

  4. HDU 2089 不要62【数位DP入门题】

    不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  5. HDU 2089 不要62(数位dp入门)

    题意:统计区间 [a,b] 中不含 4 和 62 的数字有多少个. 题解:这是数位DP的入门题了,首先要理解数DP的原理,DP[i][j]:代表第i位的第j值,举个栗子:如4715   数位数是从右向 ...

  6. HDU 2089 - 不要62 - [数位DP][入门题]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089 Time Limit: 1000/1000 MS (Java/Others) Memory Li ...

  7. LightOJ 1140 计数/数位DP 入门

    题意: 给出a,b求区间a,b内写下过多少个零 题解:计数问题一般都会牵扯到数位DP,DP我写的少,这道当作入门了,DFS写法有固定的模板可套用 dp[p][count] 代表在p位 且前面出现过co ...

  8. 51nod 1042 数位dp

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1042 1042 数字0-9的数量 基准时间限制:1 秒 空间限制:131 ...

  9. HDU-2089不要62-暴力或数位DP入门

    不要62 题意:给定区间,求在这个区间中有多少个数字,不包含4且不包含62: 这道题作为数位DP的入门题: 暴力也是可以过 #include<cstdio> #include <io ...

随机推荐

  1. 解决跨域HttpResponseJsonCORS, HttpResponseCORS 返回字典数据

    #!/usr/bin/python # -*- coding: UTF-8 -*- import json from django.http import HttpResponse def HttpR ...

  2. 斯坦福大学Andrew Ng - 机器学习笔记(8) -- 推荐系统 & 大规模机器学习 & 图片文字识别

    大概用了一个月,Andrew Ng老师的机器学习视频断断续续看完了,以下是个人学习笔记,入门级别,权当总结.笔记难免有遗漏和误解,欢迎讨论. 鸣谢:中国海洋大学黄海广博士提供课程视频和个人笔记,在此深 ...

  3. php采集

    采集思路   采集程序的思路很简单大体可以分为以下几个步骤: 1. 获取远程文件源代码(file_get_contents或用fopen).    2.分析代码得到自己想要的内容(这里用正则匹配,一般 ...

  4. mysql第二天作业

    create database 数据库名 default charset utf8;use 数据库名;1.创建成绩表,字段包括:学生姓名,语文成绩,数学成绩,英语成绩create table resu ...

  5. [笔记] Ubuntu下编译ffmpeg+openh264+x264

    [下载代码]   - ffmpeg: git clone git://source.ffmpeg.org/ffmpeg.git - openh264: git clone https://github ...

  6. centos7 firewall开放查看关闭端口

    查看所有打开的端口: firewall-cmd --zone=public --list-ports 添加 firewall-cmd --zone=public --add-port=80/tcp - ...

  7. Java 基础总结(一)

    本文参见:http://www.cnblogs.com/dolphin0520/category/361055.html 1. String,StringBuffer,StringBuilder 1) ...

  8. LeetCode: Max Consecutive Ones

    这题最关键的是处理最开始连续1和最后连续1的方式,想到list一般在最前面加个node的处理方式,在最前面和最后面加0即可以很好地处理了 public class Solution { public ...

  9. oracle 任务使用

    文章访问地址:http://www.cnblogs.com/hoojo/p/oracle_procedure_job_interval.html

  10. form前台提交List<Object>对象以及后台处理

    页面: <form method="post" action="test.do" id="form"> <input ty ...