首页 > 代码库 > BZOJ 3679 数位DP
BZOJ 3679 数位DP
思路:
f[i][j]表示i位数乘积为j的方案数
j的取值最多5000多种,那就开个map存一下好了
f[i][mp[k*rec[j]]]+=f[i-1][j];
//By SiriusRen#include <map> #include <cstdio>using namespace std;#define int long longint n,L,R,tot,rec[6666],f[20][6666];map<int,int>mp;void dfs(int x){ if(x>n||mp.find(x)!=mp.end())return; mp[x]=++tot,rec[tot]=x; for(int i=2;i<=9;i++)dfs(x*i);}map<int,int>::iterator it;int calc(int m){ int p=1,base=0,now=1,ans=0; for(;10*p<=m;base++,p*=10); for(int i=1;i<=base;i++) for(int j=1;j<=tot;j++) ans+=f[i][j]; for(int i=base;i>=0;i--){ for(int j=1;j<=tot;j++) for(int k=1;k<m/p;k++) if(rec[j]*k*now<=n) ans+=f[i][j]; now=m/p*now,m%=p,p/=10; if(!now)return ans; } return ans+(now<=n);}signed main(){ scanf("%lld%lld%lld",&n,&L,&R); dfs(1),f[0][1]=1; for(int i=1;i<=18;i++) for(int j=1;j<=tot;j++) for(int k=1;k<=9;k++) if(k*rec[j]<=n)f[i][mp[k*rec[j]]]+=f[i-1][j]; printf("%lld\n",calc(R-1)-calc(L-1));}
BZOJ 3679 数位DP
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。