Tickets

Time Limit : 1000/500ms (Java/Other)   Memory Limit : 524288/262144K (Java/Other)
Total Submission(s) : 79   Accepted Submission(s) : 16
Problem Description

Conductor is quite a boring profession, as all you have to do is just to sell tickets to the passengers. So no wonder that once upon a time in a faraway galaxy one conductor decided to diversify this occupation. Now this conductor sells several tickets at a
time to each passenger. More precisely, he successively gives tickets to the passenger until the sum of the digits on all the tickets given becomes not less than some integer number k. Then this process repeats for the next passenger. Initially conductor
has a tape of tickets numbered successively from l to r, inclusive. This way of tickets distribution is quite good, because passengers are glad to get several tickets when they pay only for one. But there is one disadvantage. Since each passenger
gets several tickets, it is possible that conductor won't be able to serve all passengers. Your task is to help conductor in this difficult situation. You should calculate how many passengers is the conductor able to serve.

Input

Input file contains three integer numbers lr and k (1 ≤ l ≤ r ≤ 1018, 1 ≤ k ≤ 1000).

Output

Output should contain exactly one number — the answer to the problem.

Example(s)
sample input

sample output

40 218 57

29

题意:

给你一个区间,让你分段,分段完后一段连续的数的数位和要大于K,问这样的段有多少
题解:
朴素的数位DP肯定不能过,这题在这篇国家集训队论文上出现过,作者讲的比较清楚(算法合集之《浅谈数位类统计问题》),
我们设dp[i][sum][rem]表示考虑到第i为,i之前的数位和为sum,当前还有多少rem没有用来分段,这里我用一个pair型来记录满足条件的段数cnt,和在这个dp状态下的rem,然后采用记忆化搜索,就能大大降低时间复杂度,为什么?因为当考虑到第i位时,前面的和为sum,只要不是边界情况下后面的每一个数位都可以取0-9,所以如果之前算出了当前的这个状态,那么就可以直接返回这个状态的值,这就是记忆化搜索的优势。
我看完论文后,对rem的概念还是比较模糊,然后自己模拟了一遍,最后懂了这个的意思,就拿样列来说,40—218内找满足条件的分段数,我们最开始sum和rem都为0,从40开始搜,40的数位和sum为4,然后dfs到最后一位,发现sum+rem小于57,所以到40这个数的时候不能分为一段,然后返回cnt=0,rem=sum+rem=4,就代表40这个数还没用于分段,然后回溯回去搜41,此时的sum为5,rem为4,然后发现sum+rem还是小于57,就返回cnt=0,rem=sum+rem=9,代码40和41这两个数都没用于分段,最后一直搜到47的时候sum=11,rem=49,然后发现sum+rem>=57成立,返回cnt=1,rem=0,表示到这个数可以分为一段,然后rem为0表示分完一段后,没用的数,没有了,所以对应的数位和rem为0。
 #include<cstdio>
#include<cstring>
#include<algorithm>
#define F(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long LL;
typedef pair<LL,LL>P;
int l[],r[],ln,rn,vis[][][];
LL a,b,m;
P dp[][][];
P dfs(int pos=rn,int sum=,int rem=,bool up=,bool dn=){
if(!pos)if(sum+rem>=m)return P(,);else return P(,sum+rem);
if(vis[pos][sum][rem]&&!up&&!dn)return dp[pos][sum][rem];
int st=dn?l[pos]:,end=up?r[pos]:;P ans=P(,rem);
F(i,st,end){
P tp=dfs(pos-,sum+i,ans.second,up&&i==end,dn&&i==st);
ans.first+=tp.first,ans.second=tp.second;
}
if(!up&&!dn)dp[pos][sum][rem]=ans,vis[pos][sum][rem]=;
return ans;
} int main(){
while(~scanf("%I64d%I64d%I64d",&a,&b,&m)){
memset(vis,,sizeof(vis));
for(rn=;b;b/=)r[++rn]=b%;
for(ln=;ln<rn;a/=)l[++ln]=a%;
printf("%I64d\n",dfs().first);
}
return ;
}
 

SGU_390_Tickets(另类数位DP)的更多相关文章

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

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

  2. bzoj1026数位dp

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

  3. uva12063数位dp

    辣鸡军训毁我青春!!! 因为在军训,导致很长时间都只能看书yy题目,而不能溜到机房鏼题 于是在猫大的帮助下我发现这道习题是数位dp 然后想起之前讲dp的时候一直在补作业所以没怎么写,然后就试了试 果然 ...

  4. HDU2089 不要62[数位DP]

    不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  5. 数位DP GYM 100827 E Hill Number

    题目链接 题意:判断小于n的数字中,数位从高到低成上升再下降的趋势的数字的个数 分析:简单的数位DP,保存前一位的数字,注意临界点的处理,都是套路. #include <bits/stdc++. ...

  6. 数位dp总结

    由简单到稍微难点. 从网上搜了10到数位dp的题目,有几道还是很难想到的,前几道基本都是模板题,供入门用. 点开即可看题解. hdu3555 Bomb hdu3652 B-number hdu2089 ...

  7. 数位DP入门

    HDU 2089 不要62 DESC: 问l, r范围内的没有4和相邻62的数有多少个. #include <stdio.h> #include <string.h> #inc ...

  8. 数位DP之奥义

    恩是的没错数位DP的奥义就是一个简练的dfs模板 int dfs(int position, int condition, bool boundary) { ) return (condition ? ...

  9. 浅谈数位DP

    在了解数位dp之前,先来看一个问题: 例1.求a~b中不包含49的数的个数. 0 < a.b < 2*10^9 注意到n的数据范围非常大,暴力求解是不可能的,考虑dp,如果直接记录下数字, ...

随机推荐

  1. poll机制分析[转]

    所有的系统调用,基于都可以在它的名字前加上"sys_"前缀,这就是它在内核中对应的函数.比如系统调用open.read.write.poll,与之对应的内核函数为:sys_open ...

  2. while循环与i--

    int i = 5;         while(i-- > 0){             System.out.println("i="+i);         } 打印 ...

  3. Astyle编程语言格式化工具的说明

    1.工具->扩展和更新,搜astyle插件,下载安装重启,当前是2.0版本. 2.工具->选项->AStyle Formatter->Edit,填入下面的,点击save,确定. ...

  4. 《C++ Primer》之面向对象编程(四)

    纯虚函数 在前面所提到过的 Disc_item 类提出了一个有趣的问题:该类从 Item_base 继承了 net_price 函数但没有重定义该函数.因为对 Disc_item 类而言没有可以给予该 ...

  5. centos下安装与配置Apache方法

    下面以httpd-2.0.55.tar.gz版本为例,介绍Apache在Linux中的安装过程:1.解压和解包安装文件:gzip -d httpd-2.0.55.tar.gztar xvf httpd ...

  6. varnish缓存安装使用

    varnish PDF http://files.cnblogs.com/jimingsong/varnish.pdf 目前介绍CentOS6.4-64位系统 yum安装varnish: 配置varn ...

  7. IT人为什么难以拿到高薪?【转帖】

    最近在论坛里看到很多人发牢骚,说薪水少,可在我看来,你们这样的人拿得到高薪才怪! 我先问一句:这里有多少人是本科的?有多少人是正规本科的(不算自考,成考和专升本)?有多少人是有学位的?有多少有学位的是 ...

  8. flash/flex 编译错误汇总

    来源:http://blog.chinaunix.net/uid-366408-id-116463.html 代码 消息 说明   1000 对 %s 的引用不明确. 引用可能指向多项.例如,下面使用 ...

  9. mongodb导出数据

    导出 -d  数据库名 -u 用户名 -p 密码 -c  要导出的表名 -o 要到出的文件地址及类型 C:\Users\Administrator>mongoexport -d fh -u we ...

  10. Redis和Memcached的区别【转】

    如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点:1 Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储.2 Redis支持数据 ...