【数位dp】bzoj1799: [Ahoi2009]self 同类分布
各种奇怪姿势的数位dp
Description
Sample Input
Sample Output
HINT
【约束条件】1 ≤ a ≤ b ≤ 10^18
题目分析
好像10^18左右的数位dp都是乱搞就好了
既然是要求整除原数,那么数位之和肯定要放进状态里,并且枚举数位总和地去dp。
看上去好像$f[i][j]$表示后面$i$位总和为$j$的合法方案数不就好了吗?
考虑这种状态的转移会发现,从后面做上来不可行啊,没办法处理在开头加上一个数后,能整除数位之和的方案。并且我们启发性地发现,为了转移的合法性,需要在状态里加上余数来限制状态(因为当前不能整除的或许后面能够整除了;反之亦有可能)。
于是想到用$f[i][j][k][done(0/1)]$表示前$i$位和为$j$,除数位总和$sum$的余数为$k$,是否达到上限(done=1表示达到)的合法状态数。
最终答案显然是$\sum{f[digits][sum][0][0]+f[digits][sum][0][1]}$。当然这个sum是要枚举过去的。
如此,转移也就不难处理了,并且时间复杂度也是正确的(位数最大就18)
#include<bits/stdc++.h>
typedef long long ll; ll a,b;
ll f[][][][];
int digit[]; ll read()
{
char ch = getchar();
ll num = ;
bool fl = ;
for (; !isdigit(ch); ch = getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch = getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
ll solve(ll x)
{
for (digit[]=; x; x/=)
digit[++digit[]] = x%;
for (int i=; i<=digit[]/; i++)
std::swap(digit[i], digit[digit[]-i+]);
int mx = digit[]*;
ll ret = ;
for (int sum=; sum<=mx; sum++)
{
memset(f, , sizeof f);
f[][][][] = ;
for (int i=; i<digit[]; i++)
for (int j=; j<=i*; j++)
for (int k=; k<sum; k++)
for (int p=; p<=; p++)
if (f[i][j][k][p])
for (int t=; t<=; t++){
if (p&&digit[i+] < t) break;
f[i+][j+t][(*k+t)%sum][p&&digit[i+]==t] += f[i][j][k][p];
}
ret += f[digit[]][sum][][]+f[digit[]][sum][][];
}
return ret;
}
int main()
{
a = read(), b = read();
printf("%lld\n",solve(b)-solve(a-));
return ;
}
END
【数位dp】bzoj1799: [Ahoi2009]self 同类分布的更多相关文章
- [BZOJ1799][Ahoi2009]self 同类分布(数位dp)
题目描述 给出两个数 a,ba,b ,求出 [a,b][a,b] 中各位数字之和能整除原数的数的个数. 输入输出格式 输入格式: 一行,两个整数 aa 和 bb 输出格式: 一个整数,表示答案 输入输 ...
- BZOJ1799 [Ahoi2009]self 同类分布[数位DP]
求出[a,b]中各位数字之和能整除原数的数的个数. 有困难的一道题.被迫看了题解:枚举每一个各位数字的和($<=162$),设计状态$f[len][sum][rest]$表示dp后面$len$位 ...
- bzoj1799: [Ahoi2009]self 同类分布
数位dp 先从1到162枚举各位数之和 s[i][j][k][l]表示i位数,第一位小于等于j,当前各位数字和为k,当前取模余数为l的方案数 然后脑补一下转移就行了 详见代码 #include < ...
- bzoj 1799: [Ahoi2009]self 同类分布 数位dp
1799: [Ahoi2009]self 同类分布 Time Limit: 50 Sec Memory Limit: 64 MB[Submit][Status][Discuss] Descripti ...
- [Ahoi2009]self 同类分布
1799: [Ahoi2009]self 同类分布 Time Limit: 50 Sec Memory Limit: 64 MBSubmit: 2357 Solved: 1079[Submit][ ...
- BZOJ 1799 - [AHOI2009]self 同类分布 - 枚举 数位DP
Description 找出$[L, R]$ 区间内有多少数, 各位数字和 能整除原数 Solution 枚举每个可能的数字和, 进行数位DP即可 , 水爆 Code #include<cstd ...
- 【AHOI2009】同类分布 题解(数位DP)
题目大意:求$[l,r]$中各位数之和能被该数整除的数的个数.$0\leq l\leq r\leq 10^{18}$. ------------------------ 显然数位DP. 搜索时记录$p ...
- 【BZOJ】1799: [Ahoi2009]self 同类分布
[题意]给出a,b,求出[a,b]中各位数字之和能整除原数的数的个数.1 ≤ a ≤ b ≤ 10^18 [算法]数位DP [题解] 感觉这种方法很暴力啊. 枚举数位和1~162(不能枚举0,不然会模 ...
- 数位dp初探
我这种蒟蒻就一直不会写数位dp.. 于是开了个坑.. 1833: [ZJOI2010]count 数字计数 这道被KPM大爷说是入门题..嗯似乎找找规律然后减掉0的情况后乱搞就可以了..(但是还是写了 ...
随机推荐
- math(2018.10.27)
20%的数据直接暴搜就行,接下来我们考虑哪些数不能够出现在同一个集合中,就连一 条边,我们会发现前
- iOS 同一个View识别单击和双击手势
1.给View添加手势 //view添加两个手势检测方法 self.currentPlayerView.userInteractionEnabled = YES; UITapGestureRecogn ...
- re 模块的重新整理
RE模块 import re 的常用操作 查找 1. findall : ret = re.findall('\d+'.'sjkhk172按实际花费928') #正则表达式,待匹配的字符串,flag ...
- morphia(3)-查询
1.查询所有 @Test public void query() throws Exception { final Query<Employee> query = datastore.cr ...
- JS中的关系操作符与自动转型
很多时候对数据操做时都会遇到数据转换,有的是显示转化,有的是隐式转化,即调用默认的规则进行数据转换,经常会把数据转换的方式搞混,于是就花了点时间做了个小小的总结: 一元操作符(--,++,-,+)作用 ...
- 记次浙大月赛 134 - ZOJ Monthly, June 2014
链接 虽做出的很少,也记录下来,留着以后来补..浙大题目质量还是很高的 B 并查集的一些操作,同类和不同类我是根据到根节点距离的奇偶判断的,删点是直接新加一个点,记得福大月赛也做过类似的,并差集的这类 ...
- SVM为什么需要核函数
生存?还是毁灭?——哈姆雷特 可分?还是不可分?——支持向量机 之前一直在讨论的线性分类器,器如其名(汗,这是什么说法啊),只能对线性可分的样本做处理.如果提供的样本线性不可分,结果很简单,线性分类器 ...
- java定时读取文件
在项目中经常会用到定时器,在笔试或者面试中也会经常问到定时器和IO流. public class TimerDemo { public static void main(String[] args) ...
- xp密钥
Windows XP 专业版 : CCC64-69Q48-Y3KWW-8V9GV-TVKRM
- siege4压测脚本示例
agent="Siege 1.0"rcconfig="/opt/siege4.0/etc/siegerc"concurrent=$1repet=$2url=&q ...