题目:数字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. [HTML] CSS3 文本效果

    CSS3 文本效果 CSS3中包含几个新的文本特征. 在本章中您将了解以下文本属性: text-shadow word-wrap 浏览器支持

  2. IPTV视频基本概念

      480x320, 640x480 标清 1024x720p 高清 1920x1080i (隔行扫描) 也属于高清 1920x1080p 全高清 3840x2160,7680x4320 超(高)清 ...

  3. maximo功能修改笔记

    经过前几次的简单的修改系统功能,对maximo的bean开发已经有了一定了解,现在是耗时近两个礼拜来修改了一项系统功能,所用到的知识 Bean Fld, 下面我认真总结修改功能过程中的学到的知识: 目 ...

  4. TListView的一些操作

    1,让滚动条滚动的API SetScrollPos int SetScrollPos(     _In_  HWND hWnd,     _In_  int nBar,     _In_  int n ...

  5. objective c,copy, mutableCopy区别

    copy总是返回不能被修改的对象,mutableCopy返回可以被修改的对象 例: NSArray *array = @[@"test", @"test2"]; ...

  6. JStorm第一个程序WordCount详解

    一.Strom基本知识(回顾) 1,首先明确Storm各个组件的作用,包括Nimbus,Supervisor,Spout,Bolt,Task,Worker,Tuple nimbus是整个storm任务 ...

  7. VBS使用Scripting.Dictionary字典对象

    Scripting.Dictionary是个很有用的组件,其创建了类似于Key索引对应Value值的字典对象,并且在其内部提供了快速索引访问的机制,可以让我们通过Key直接索引到指定的Value,比遍 ...

  8. {CSDN}{英雄会}{反相互}

    思路: 给定一个字符串,求两个不重叠的字串,他们翻转互补.其中一个字符串可以是删掉最多两个字符的原字符串子串. 动态规划,由于可以对子串进行删除操作,我首先想到了LCS问题,但需要枚举所有的长度,这样 ...

  9. Framework7--Test

    <!doctype html> <html> <head> <title>{{title}}</title> <meta charse ...

  10. jquery动态创建页面元素

    jquery用$()方法动态创建一个页面元素,例如: var $div=$("<div title='动态创建页面元素'>欢迎创建一个新的div</div>" ...