数位DP (51nod)
题目:数字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)的更多相关文章
- 51nod 1009 - 数字1的数量 - [数位DP][模板的应用以及解释]
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1009 基准时间限制:1 秒 空间限制:131072 KB 给 ...
- 51nod 1042 数位dp
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1042 1042 数字0-9的数量 基准时间限制:1 秒 空间限制:131 ...
- 51nod 1009 数位dp入门
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1009 1009 数字1的数量 基准时间限制:1 秒 空间限制:13107 ...
- 51NOD 1623 完美消除 数位DP
题目描述: 定义数的消除操作为选定[L,R,x],如果数的第L到第R位上的数字都大于等于x,并且这些数都相等,那么该操作是合法的(从低位到高位编号,个位是第一位,百位是第二位……),然后将这些位数上的 ...
- 51nod 1009 数字1的数量(数位dp模板)
给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数. 例如:n = 12,包含了5个1.1,10,12共包含3个1,11包含2个1,总共5个1. 数位dp的模板题 ...
- 51Nod 1009 数字1的个数 | 数位DP
题意: 小于等于n的所有数中1的出现次数 分析: 数位DP 预处理dp[i][j]存 从1~以j开头的i位数中有几个1,那么转移方程为: if(j == 1) dp[i][j] = dp[i-1][9 ...
- 51nod1043(数位dp)
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1043 题意:中文题诶- 思路:数位dp 我们用dp[i][j ...
- 1043 幸运号码 数位DP
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1043 设dp[i][j]表示前i位数中,i位数的和为j时的所有情况. 转 ...
- 【BZOJ1662】[Usaco2006 Nov]Round Numbers 圆环数 数位DP
[BZOJ1662][Usaco2006 Nov]Round Numbers 圆环数 Description 正如你所知,奶牛们没有手指以至于不能玩"石头剪刀布"来任意地决定例如谁 ...
- bzoj1026数位dp
基础的数位dp 但是ce了一发,(abs难道不是cmath里的吗?改成bits/stdc++.h就过了) #include <bits/stdc++.h> using namespace ...
随机推荐
- SSH框架流程
流程图 具体步骤 一.实体类 //Serializable在网络的环境下做类传输public class Category implements Serializable { private Inte ...
- Linux系统man查询命令等级及意义
1:用户命令,可由任何人启动的 2:系统调用,由内核提供的函数 3:库函数 4:设备,/dev目录下的特殊文件 5:文件格式描述,例如/etc/passwd 6:游戏 7:杂项,例如宏命令包.惯例等 ...
- 聊聊javascript中的面向对象
面向对象这个东西一直晕晕乎乎的,正好这段时间没有活,可以好好整理整理了! 1.什么是对象? 其实这个说起来一切东西都是对象 2.目前我们使用对象的时候,使用的是两种设计模式杂糅起来的 分别是原型模式和 ...
- 一个等待页面加载完毕的loading动画
1 html 部分 <!DOCTYPE html><html><head><meta http-equiv="Content-Type" ...
- Django模板格式
变量 {{ 变量名称 }} 块 {% block 块名称 %} 判断 根据布尔值判断: {% if 布尔值 %} 操作 {% endif %} 根据两者是否相等判断: {% ifequals 变量1 ...
- 调用Ria Service中方法的各种方式
前端界面后台: using System; using System.Collections.Generic; using System.Linq; using System.Net; using S ...
- Python 集合方法总结
1.添加一个元素: add(...) Addan element to a set. 1 2 3 4 >>> a = {'shaw',11,22} >>>a. ...
- 在eclipse之中使用Junit
使用Junit单位测试,能够一定程度上减小项目bug的产生.很多时候,我们都是在main函数里面单独去测试一个方法,这样的测试非常不方便.使用Junit可以是测试单位和项目代码分离,一次性测试多个方法 ...
- screen 命令
# screen [-AmRvx -ls -wipe][-d <作业名称>][-h <行数>][-r <作业名称>][-s ][-S <作业名称>] 参 ...
- Tara's Beautiful Permutations 组合数学
https://www.hackerrank.com/contests/hourrank-15/challenges/taras-beautiful-permutations 首先先统计一下个数为2的 ...