数位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 ...
随机推荐
- PASCAL==CALLBACK==WINAPI==__stdcall
VC里面:PASCAL==CALLBACK==WINAPI==__stdcall _stdcall是Pascal程序的缺省调用方式,通常用于Win32 Api中,函数采用从右到左的压 ...
- unity3d c#脚本定义Transform
Transform n = Instantiate(newobject,transform.position,transform.rotation) as Transform;Instantiate返 ...
- 微信订阅号里实现oauth授权登录,并获取用户信息 (完整篇)
摘要 这段时间一直有人问我,订阅号实现的oauth授权登录的问题,之前写的比较简单,很多人不明白.众所周知,微信公众号分订阅号.服务号.企业号:每个号的用途不一样,接口开放程度也不一样.微信还有个扯淡 ...
- 2.2 节的练习--Compiler principles, technologys, &tools
2.2 节的练习 2.2.1 考虑下面的上下文无关文法: S -> S S + | S S * | a 试说明如何使用该文法生成串 aa+a* 试为这个串构造一颗语法分析树 ⧗ 该文法生成的语言 ...
- Thinkpad 笔记本VMware Workstation 安装虚拟机出现“此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态”解决方法
今天在使用VMware打算在机器中安装新的虚拟机时,出现"此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态"错误如下: 提示信息: 已将该虚拟机配 ...
- 在Linux下给mysql创建用户并分配权限及问题解决方案
在linux下安装mysql请参考在linux系统中安装mysql服务器详细步骤 1.新建用户 //登录MYSQL @>mysql -u root -p @>密码 //创建用户 mysql ...
- 【转】提高VR渲染速度的关键
提高VR渲染速度的关键,这个教程比以往的教程都要重要很多,如果你是刚刚步入学习和上升阶段那么这将是你必须要看的东西,他会让你迅速提升技能达到比你死看书本好很多的效果,不多说上教程 VR的基本渲染方 ...
- Windows service无法删除怎么办?
自己用c#创建的windows service, 安装后,执行installutil /u 状态变成disable,却删除不了.删除的时候提示"The specified service ...
- UVa 414 - Machined Surfaces
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=94&page=s ...
- tdd 和 make file,以及cygwin
等我把这本书看完,好好总结一下. 还要把以前的博客文字整理一下