【数位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的情况后乱搞就可以了..(但是还是写了 ...
随机推荐
- Spring Boot Autowirted注入找不到Bean对象解决方法
报错:Consider defining a bean of type 'xxxxxxxxxxxxx' in your configuration 1. 你应该在 ApplyApplication 启 ...
- Java 时区(转)
http://blog.csdn.net/wangpeng047/article/details/8560690
- error: unrecognized command line option "-std=c11" 解决办法
今天在安装php版本 grpc扩展的时候报错如下: cc1: error: unrecognized command line option "-std=c11" cc1: war ...
- Codeforces 1138B(列方程枚举)
构造模拟要分情况讨论感觉不是够本质,然后官解是因为只有四个量所以可以根据限制条件列两个方程,再枚举一下解就可以了. const int maxn = 5000 + 5; int n, c[maxn], ...
- windows安装redis和PHP redis扩展
1.安装Redis (1)这里选择在github官网上下载Redis,地址:Redis下载地址 下载压缩包(如下图),并解压到本地目录,我放在D:\wamp\redis\redis-windows ( ...
- find搜索文件系统,实时搜索
find搜索文件系统.实时搜索 find[目录][条件][动作] [目录] 不输入目录代表当前目录 find find /etc ----------------------------------- ...
- vim编辑器高级应用
1. vim主要模式介绍 命令模式.命令行模式.编辑模式 字符操作:i 当前插入, I行首插入, a当前字符之后插入,A行首插入, ESC退出当前模式 2. vim命令模式 3. vim插入模式 4. ...
- WebService学习之旅(四)Apache Axis2的安装
一.Axis2简介 Axis2是目前使用较多的WebService引擎,它是Axis1.x的升级版本,不仅支持SOAP1.1和SOAP1.2,而且也提供了对REST风格WebService的支持. A ...
- LR中操中MySQL脚本模板
Action(){ char chQuery[128]; MYSQL *Mconn; int result; //引入mysql动态链接库 lr_load_dll("libmysql.dll ...
- 测试ReplicaSets读写分离和故障转移
读写分离实现步骤: 从库能够进行查询就更好了,这样可以分担主库的大量的查询请求. 1) 先向主库中插入一条测试数据 rs1:PRIMARY> db.c1.insert({age:30});db. ...