前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Luogu P4127 [AHOI2009]同类分布 题解

Luogu P4127 [AHOI2009]同类分布 题解

作者头像
yzxoi
发布2022-09-19 12:52:32
2370
发布2022-09-19 12:52:32
举报
文章被收录于专栏:OI

Luogu P4127 [AHOI2009]同类分布 题解

Describe

题目链接

给出两个数a,b,求出[a,b]中各位数字之和能整除原数的数的个数。

Solution

数位dp。

DFS(x,sum,dig,lim)分别表示第x位,当前数位之和为sum,数字为dig,是否到达极限。

但是数据极大,dig会达到{10}^{18}是不可能来记忆化的,所以考虑取模

那么模多少好呢?很明显如果模sum是最好的,最后只要判断下是否等于0即可。

那么暴力跑9\times len次数位dp,求的是sum==i时的数位dp结果,最后加起来就好了。

P.S.这里参考了讨论区神仙的优化:如果最后各个数位之和绝对到不了要求的话直接return 0

Code

代码语言:javascript
复制
#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[21],m,mod,f[21][201][201][2];
inline int DFS(int x,int sum,int dig,int lim){
if(sum+9*x<mod) return 0;//优化
if(x==0) return sum==mod&&dig==0;
if(~f[x][sum][dig][lim]) return f[x][sum][dig][lim];
int Max=lim?a[x]:9,res=0;
for(int i=0;i<=Max;i++) res+=DFS(x-1,sum+i,(dig*10+i)%mod,lim&&(i==Max));
return f[x][sum][dig][lim]=res;
}
inline int solve(int n){
m=0;
while(n){
a[++m]=n%10;
n/=10;
}
int res=0;
for(mod=1;mod<=m*9;mod++) memset(f,-1,sizeof(f)),res+=DFS(m,0,0,1);//暴力枚举模数
return res;
}
int L,R;
signed main(){return scanf("%lld%lld",&L,&R),printf("%lld\n",solve(R)-solve(L-1)),0;}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-03-25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Luogu P4127 [AHOI2009]同类分布 题解
    • Describe
      • Solution
        • Code
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档