数位dp,需要记录前导0。

数位dp中需要注意统计0,00,000……这些数字。

数位dp的写法可以分为两类。由于我们通常采用记忆化搜索的方式进行dp,所以我们有一个记忆化数组。

一种是记忆化数组的意义是不通用的,对于不同case,该数组的值不同。另一种是通用的,不同case,数组的值不变。

对于第一种情况的实现比较简单,只需要將递归过程的全部参数记录在数组的维度中。

由于要记录全部的参数,数组维度高,所以空间效率低。

由于不同case要重新计算记忆化数组,所以对于多case的评判时间效率低。

模板如下:

long long dfs(int digit, bool less, bool leading_zero, ...)
{
if (digit < )
{
return ...;
}
if (memoize[digit][less][leading_zero][...] != -)
{
return memoize[digit][less][leading_zero][...];
}
int limit = less ? : f[digit];
long long ret = ;
for (int i = ; i <= limit; i++)
{
ret += dfs(digit - , less || i < f[digit], leading_zero && i==, ...);
}
return memoize[digit][less][leading_zero][...] = ret;
}

对于第二种情况,则需要对某些参数进行条件判断,记忆化数组memoize[digit]中记录的是,最低的digit位可以任意取值的情况下,我们所需要的答案。

因而,这种记忆化数组自然不会受到上界的限制。

但是实现起来复杂,如果需要条件判断的变量(在递归参数中,却不在记忆化数组中的变量)过多,则会尤为复杂。

尤其是对于那种多个数字,每个数字都有上界,同时进行dp的情况,不应该使用这种方法,而应选用第一种方法。

模板如下:

long long dfs(int digit, bool less, bool leading_zero, ...)
{
if (digit < )
{
return ...;
}
if (less && !leading_zero && memoize[digit][...] != -)
{
return memoize[digit][...];
}
int limit = less ? : f[digit];
long long ret = ;
for (int i = ; i <= limit; i++)
{
ret += dfs(digit - , less || i < f[digit], leading_zero && i == , ...);
}
if (less && !leading_zero)
{
memoize[digit][...] = ret;
}
return ret;
}

本题答案如下:

#include <cstdio>
#include <cstring>
using namespace std; const int MAX_DIGIT = ; long long n;
int f[MAX_DIGIT];
long long memoize[MAX_DIGIT][**];
int pivot; int to_digits(long long a)
{
int ret = ;
while (a > )
{
f[ret++] = a % ;
a /= ;
}
return ret;
} long long dfs(int digit, bool less, bool leading_zero, int zero_num)
{
if (digit < )
{
return zero_num;
}
if (less && !leading_zero && memoize[digit][zero_num] != -)
{
return memoize[digit][zero_num];
}
int limit = less ? : f[digit];
long long ret = ;
for (int i = ; i <= limit; i++)
{
int delta = !leading_zero && i == ? : ;
ret += dfs(digit - , less || i < f[digit], leading_zero && i == , zero_num + delta);
}
if (less && !leading_zero)
{
memoize[digit][zero_num] = ret;
}
return ret;
} long long work(long long n)
{
if (n < )
{
return ;
}
if (n == )
{
return ;
}
int len = to_digits(n);
return dfs(len - , false, true, ) + ;
} int main()
{
int t;
scanf("%d", &t);
memset(memoize, -, sizeof(memoize));
for (int i = ; i <= t; i++)
{
long long a, b;
scanf("%lld%lld", &a, &b);
printf("Case %d: %lld\n", i, work(b) - work(a - ));
}
return ;
}

Light OJ 1140的更多相关文章

  1. light oj 1140 - How Many Zeroes? 数位DP

    思路:dp[i][j]:表示第i位数,j表示是否有0. 代码如下: #include<iostream> #include<stdio.h> #include<algor ...

  2. Light oj 1140 How Many Zeroes?

    Jimmy writes down the decimal representations of all natural numbers between and including m and n, ...

  3. Light OJ 1114 Easily Readable 字典树

    题目来源:Light OJ 1114 Easily Readable 题意:求一个句子有多少种组成方案 仅仅要满足每一个单词的首尾字符一样 中间顺序能够变化 思路:每一个单词除了首尾 中间的字符排序 ...

  4. Light OJ 1429 Assassin`s Creed (II) BFS+缩点+最小路径覆盖

    题目来源:Light OJ 1429 Assassin`s Creed (II) 题意:最少几个人走全然图 能够反复走 有向图 思路:假设是DAG图而且每一个点不能反复走 那么就是裸的最小路径覆盖 如 ...

  5. Light OJ 1406 Assassin`s Creed 减少国家DP+支撑点甚至通缩+最小路径覆盖

    标题来源:problem=1406">Light OJ 1406 Assassin`s Creed 意甲冠军:向图 派出最少的人经过全部的城市 而且每一个人不能走别人走过的地方 思路: ...

  6. Light OJ 1316 A Wedding Party 最短路+状态压缩DP

    题目来源:Light OJ 1316 1316 - A Wedding Party 题意:和HDU 4284 差点儿相同 有一些商店 从起点到终点在走过尽量多商店的情况下求最短路 思路:首先预处理每两 ...

  7. light oj 1007 Mathematically Hard (欧拉函数)

    题目地址:light oj 1007 第一发欧拉函数. 欧拉函数重要性质: 设a为N的质因数.若(N % a == 0 && (N / a) % a == 0) 则有E(N)=E(N ...

  8. Light OJ 1406 Assassin`s Creed 状态压缩DP+强连通缩点+最小路径覆盖

    题目来源:Light OJ 1406 Assassin`s Creed 题意:有向图 派出最少的人经过全部的城市 而且每一个人不能走别人走过的地方 思路:最少的的人能够走全然图 明显是最小路径覆盖问题 ...

  9. Light OJ 1288 Subsets Forming Perfect Squares 高斯消元求矩阵的秩

    题目来源:Light OJ 1288 Subsets Forming Perfect Squares 题意:给你n个数 选出一些数 他们的乘积是全然平方数 求有多少种方案 思路:每一个数分解因子 每隔 ...

随机推荐

  1. Python开发【第十四篇】:Web框架本质

    Web框架本质 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...

  2. 自定义layout中需要重写的方法

    Layout类中,有3个方法是必定会被依次调用: prepareLayout: 准备所有view的layoutAttribute信息 collectionViewContentSize: 计算cont ...

  3. .NET Framework源码查看及下载

    一.资源 1.http://referencesource.microsoft.com/ 二.备注 1.可在线预览.Net Framework 4.6.1源码实现

  4. 【转】随机函数的rand、srand用法

    from:深海的小鱼儿 地址:http://www.cnblogs.com/xmphoenix/archive/2011/04/07/2008622.html 随机函数的rand.srand用法 一& ...

  5. css使 同一行内的 文字和图片 垂直居中对齐?

    设置父容器, 使 父容器 div 下的所有元素 都 垂直对齐: father-container *{ vertical-align:middle 找回密码

  6. shell学习之路:流程控制(if)

    1.单分支if条件语句 if [ 条件判断式 ];then 程序 fi 或者 if [ 条件判断式 ] then 程序 fi 注意事项: 1.if语句使用fi结尾,和一般语言使用大括号结尾不同 2.[ ...

  7. MVC中你必须知道的13个扩展点

    MVC中你必须知道的13个扩展点 pasting 转:http://www.cnblogs.com/kirinboy/archive/2009/06/01/13-asp-net-mvc-extensi ...

  8. WCF--提示:异常消息为“传入消息的消息格式不应为“Raw”。此操作的消息格式应为 'Xml', 'Json'。

    Ajax调用WCF服务... 本来用 // $.getJSON("http://localhost:16625/Service1.svc/Article_GetInfo", { } ...

  9. 微信电话本可免费拨打网络电话 通话一分钟约300K流量

    微信电话本新版本于昨日晚间发布,这是一款智能通讯增强软件,通话双方都下载此APP并开通免费通话功能就能使用微信电话本拨打免费网络电话,在对方无法接通情况下还能将音频转向语音信箱,微信电话本目前支持An ...

  10. 3.聚类–K-means的Java实现

    K-means的步骤 输入: 含n 个样本的数据集,簇的数据K 输出: K 个簇 算法步骤: 1.初始化K个簇类中心C1,C2,---Ck (通常随机选择) 2.repeat 步骤3,4 3,将数据集 ...