题目:数字1的数量

思路:首先考察不同位数以内的所有整数出现1的次数,例如四位数以内[0,9999],个十百千位均有可能出现1,

    出现1的时候,其它三个位均可以是0~9,所以假设固定一个位为1,另外三个位的可能性是10*10*10

    所以总共出现4*10*10*10 = 4000次1,所以一个完整的k位数中包含1的个数是k * 10^(k-1)

    对于一个数字n,可以将十进制拆成[p1][p2...pk]的形式,

    如果p1==0,n = [p2...pk] = [p2][p3...pk],转化为子问题

    如果p1==1,这时包含了三种情况

        1> p1位=0时,后边k-1位包含 (k-1) * 10^(k-2)个1

        2> p1位=1时,p1位重复了[p2...pk] + 1 个1

        3> p1位=1时,[p2...pk]出现1的次数(这是一个子问题,可以递归)

    如果p1 > 1,这时包含了三种情况

        1> p1位=0,1...p1-1时(共p1个可能),后面k-1位包含 (k-1) * 10^(k-2)个1

        2> p1位=1时,p1位重复了10^(k-1)个1

        3> p1位=p1时,[p2...pk]出现1的次数(这是一个子问题,可以递归)

    代码是根据这个原理从后往前累加的

容易得到状态转移方程:设dp[i]为数位i及其之后的数位的1出现次数;len为数的长度;k为当前dp[i]的位置;a[i]用于存储数;

        if(a[i] == 0) dp[i] +=  dp[i+1];

        if(a[i] == 1) dp[i] +=  (k-1) * 10^(k-2) + [a[i+1]..a[len]] + 1 +dp[i+1];

        if(a[i] > 1)   dp[i] +=  a[i] * (k-1) * 10^(k-2) + 10^(k-1) + dp[i+1];

        

#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <time.h>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <set> #define c_false ios_base::sync_with_stdio(false); cin.tie(0)
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3f
#define zero_(x,y) memset(x , y , sizeof(x))
#define zero(x) memset(x , 0 , sizeof(x))
#define MAX(x) memset(x , 0x3f ,sizeof(x))
#define swa(x,y) {LL s;s=x;x=y;y=s;}
using namespace std ;
#define N 50005 const double PI = acos(-1.0);
typedef long long LL ;
char num[];
LL dp[];
int len,number;
int pow(int k){ int s =; for(int i = ; i<k; i++)s*=;return s;}
LL cal(){
zero(dp);
int base = ;
int k;
for(int i = len-; i >= ; i--){
int s = num[i] - '';
k = len - i;
if(s == )
dp[i] += dp[i+];
if(s == )
dp[i] += (k-)*pow(k-) + number + + dp[i+];
if(s > )
dp[i] += s*(k-)*pow(k-) + pow(k-) +dp[i+];
//cout<<i<<" "<<dp[i]<<endl;
number += base * s;
base *= ;
}
return dp[];
}
int main(){
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
//ios_base::sync_with_stdio(false); cin.tie(0);
scanf("%s", num);
len = strlen(num);
number = ;
printf("%I64d\n",cal());
return ;
}

        

数位DP (51nod)的更多相关文章

  1. 51nod 1009 - 数字1的数量 - [数位DP][模板的应用以及解释]

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1009 基准时间限制:1 秒 空间限制:131072 KB 给 ...

  2. 51nod 1042 数位dp

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

  3. 51nod 1009 数位dp入门

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

  4. 51NOD 1623 完美消除 数位DP

    题目描述: 定义数的消除操作为选定[L,R,x],如果数的第L到第R位上的数字都大于等于x,并且这些数都相等,那么该操作是合法的(从低位到高位编号,个位是第一位,百位是第二位……),然后将这些位数上的 ...

  5. 51nod 1009 数字1的数量(数位dp模板)

    给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数. 例如:n = 12,包含了5个1.1,10,12共包含3个1,11包含2个1,总共5个1.   数位dp的模板题   ...

  6. 51Nod 1009 数字1的个数 | 数位DP

    题意: 小于等于n的所有数中1的出现次数 分析: 数位DP 预处理dp[i][j]存 从1~以j开头的i位数中有几个1,那么转移方程为: if(j == 1) dp[i][j] = dp[i-1][9 ...

  7. 51nod1043(数位dp)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1043 题意:中文题诶- 思路:数位dp 我们用dp[i][j ...

  8. 1043 幸运号码 数位DP

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1043 设dp[i][j]表示前i位数中,i位数的和为j时的所有情况. 转 ...

  9. 【BZOJ1662】[Usaco2006 Nov]Round Numbers 圆环数 数位DP

    [BZOJ1662][Usaco2006 Nov]Round Numbers 圆环数 Description 正如你所知,奶牛们没有手指以至于不能玩"石头剪刀布"来任意地决定例如谁 ...

  10. bzoj1026数位dp

    基础的数位dp 但是ce了一发,(abs难道不是cmath里的吗?改成bits/stdc++.h就过了) #include <bits/stdc++.h> using namespace ...

随机推荐

  1. oracle查询小结

    一.查询某表中某列值相同的记录: select * from t_acct_map where acct_id in (     select acct_id from t_acct_map grou ...

  2. 14. Reverse Linked List II

    Reverse Linked List II Reverse a linked list from position m to n. Do it in-place and in one-pass. F ...

  3. google快捷键

          使用快捷键的好处不言自明,如果能过直接访问google自然有对应的帮助文档以供参考,不过为了方便起见,还是将自己觉得有用的信息收藏到自己访问无障碍的地方吧! 一:以下快捷键适用于Windo ...

  4. C#(Winform) Http 发送数据

    Get方式 private string HttpGet(string url, string postData) { HttpWebRequest request = (HttpWebRequest ...

  5. Swift 协议

    /// 一般情况下,定义的协议都必须实现 protocol SomeProtocal { func doSomething() } /// 定义一个类,并且遵守协议 class Teacher:Som ...

  6. Inside The C++ Object Model - 04 C++对象模型的一个简单示例

    首先定义一个类X class X { public: X(); X(const X& x); virtual ~X(); virtual foo(); } 再来一段代码: X foobar() ...

  7. 【转】你真的理解Python中MRO算法吗?

    你真的理解Python中MRO算法吗? MRO(Method Resolution Order):方法解析顺序. Python语言包含了很多优秀的特性,其中多重继承就是其中之一,但是多重继承会引发很多 ...

  8. mysql的从头到脚优化之数据库引擎的选择(转载)

    一. Mysql常用的存储引擎包括Innodb和Myisam以及memory引擎,但是最常用的莫过于Innodb引擎和MyISAM引擎,下边分别做下记录和比较: 下面思考下这几个问题: 你的数据库需要 ...

  9. java基础知识点复习

    第一天: JRE.JDK是什么? Jre java运行环境.Jre = java虚拟机+核心类库(辅助java运行的文件) Jdk:java开发工具集jdk = jre+java的开发工具 2. 配置 ...

  10. smarty模板的安装配置

    第一步:下载Smarty模版源码包了    百度一下“Smarty下载”,下载最新版本的Smarty模版第二部:解压缩,将下载好的Smarty包解压缩    右键->解压到当前文件夹...你懂的 ...