当前位置: 首页 > news >正文

P9640 [SNCPC2019] Digit Mode

P9640 [SNCPC2019] Digit Mode

很不常规的数位 DP。

下文记:

  • \(n\) 为原数,\(num\) 为实际填写的数。
  • \(m(num)\)\(num\) 各数位的众数。
  • \(c_i\) 为搜索过程中数码 \(i\) 填写的次数。
  • \(n\) 的最高位为 \(len\),最低位为 \(1\)

在 DFS 过程中计算 \(m(num)\),需要的上下文信息太多(比如整个 \(c\) 数组),状态数太大。

一个常用的技巧是“提前钦定”,即枚举 \(m(num)\) 的值 \(x\),该众数的出现次数 \(y\),看有多少个 \(num\) 满足条件(比如 P4127 同类分布 - 题解)。

在主函数中钦定,我们发现仍不好做。原因在于有前导零和当前位取值范围的限制。

既然如此,我们不妨挪到搜索过程中,在每个“既不是前导零,也没有取值范围限制”的数位上钦定。

具体来说,当前在填写数位 \(p\),若 !lim&&!zro,我们即可枚举众数 \(x\),再枚举其出现次数 \(y(\max\{1,c_x\}\le y\le )\)

由于没有 limzro 的限制,所以每个数码的最多填写次数是固定的,更具体些:

\[limit_i=y-c_i-[i>x]\quad (i\ne m) \]

接下来我们要做的,是填充剩下的 \(p\) 位。

  • \(x\) 的次数已经固定为 \(y\),所以要占据 \(p\) 位中的 \(y-c_x\) 位。
  • 其他数的次数不固定,但必须 \(\le limit_i\)

第二条可以用类似多重背包的方式进行转移。记 \(f_{i,j}\) 为前 \(i\) 个数码,共占据了 \(j\) 个位置的方案数。则有转移(\(x\) 不参与,\(limit\) 只有 \(9\) 个位置):

\[f_{i,j}=\sum_{k=0}^{limit_i} f_{i-1,j-k}\times \binom{j}{k} \]

最终对答案的贡献为:

\[f_{9,p-(y-c_x)}\times \binom{p}{y-c_x} \]

下面是一个无关紧要的优化:

注意到一些同构,可令 \(F_{i,j}=\dfrac{f_{i,j}}{j!}\),则转移为:

\[F_{i,j}=\sum_{k=0}^{limit_i} \frac{F_{i-1,j-k}}{k!} \]

最终对答案的贡献为:

\[F_{9,p-(y-c_x)}\times \frac{p!}{(y-c_x)!} \]

这样来做,码量和常数都会小一些。

至于不满足 !lim&&!zro,就按正常的数位 DP 往下搜即可。

如果搜到了末尾,就暴力判定。

时间复杂度 \(O(B^4 N^3)\)

点击查看代码
#include<bits/stdc++.h>
#define int long long
#define eb emplace_back
using namespace std;
const int N=55,P=1e9+7;
int t,a[N],len,c[10],fac[N],inv[N];
string s;
inline int qp(int x,int n){int a=1;while(n){if(n&1) a=a*x%P;x=x*x%P,n>>=1;}return a;
}
inline int bf(){int x=0,p=0;for(int i=9;~i;i--) if(c[i]>x) x=c[i],p=i;return p;
}
inline int calc(vector<int>& v,int s){//求方案数if(s<0) return 0;vector<int> f(s+1),g(s+1);f[0]=1;for(int i:v){g.clear();g.resize(s+1);for(int j=0;j<=s;j++){for(int k=0;k<=i&&j+k<=s;k++){(g[j+k]+=f[j]*inv[k])%=P;}}f=g; }return f[s];
}
inline int dfs(int p,bool lim,bool zro){if(!p) return bf();int ans=0;if(!lim&&!zro){//枚举众数x及其出现次数yfor(int x=1;x<10;x++){for(int y=max(1ll,c[x]);y<=c[x]+p;y++){vector<int> w;for(int k=0;k<x;k++) w.eb(y-c[k]);for(int k=x+1;k<10;k++) w.eb(y-c[k]-1);bool flg=1;for(int i:w) if(i<0){flg=0;break;}if(flg) ans+=fac[p]*inv[y-c[x]]%P*calc(w,p-y+c[x])%P*x;}}}else{int rig=lim?a[p]:9;for(int i=0;i<=rig;i++){bool tzro=zro&&!i;if(!tzro) c[i]++;ans+=dfs(p-1,lim&&i==rig,tzro);if(!tzro) c[i]--;}}return ans%P;
}
inline int solve(string& s){len=s.size();for(int i=0;i<len;i++) a[len-i]=s[i]-'0';return dfs(len,1,1);
}
signed main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);fac[0]=inv[0]=1;for(int i=1;i<N;i++){//预处理阶乘及其逆元fac[i]=fac[i-1]*i%P;inv[i]=qp(fac[i],P-2);}cin>>t;while(t--){cin>>s;cout<<solve(s)<<"\n";}return 0;
}
http://www.jsqmd.com/news/34788/

相关文章:

  • 2025年质量好的湖北开天智能热门推荐榜
  • 2025年枫叶租车融资权威深度解析:双引擎战略重塑中高端用车市场格局
  • 2025 年枫叶租车融资权威深度解析:双引擎驱动出行服务品质迭代升级
  • 2025 年枫叶租车公司权威深度解析:双引擎布局改写中高端出行服务规则
  • 深入解析:1.6虚拟机
  • 2025年枫叶租车公司权威深度解析:双引擎驱动中高端租车市场创新升级
  • 2025 年枫叶租车公司权威深度解析:双引擎战略引领中高端租车行业变革
  • 2025年枫叶租车公司权威深度解析:双引擎战略引领中高端租车市场变革
  • 数据结构进阶
  • successful
  • 2025年知名的恩施装修半包热门推荐榜
  • 裁员下的上海
  • 2025.11.7 测试
  • 不务正业
  • 开源项目Url-Shorten-Worker时隔多年再次更新,新增人机验证码功能,创建短链接时需要人机验证--基于Cloudflare Worker的长链接转短链接项目(轻松拥有属于自己的短网址)
  • 【】发送与接收
  • 1.2.3.4.5.6.7.8.9.10.
  • linux分区扩容
  • DISM-Get-cmds
  • AI元人文:智能理性主体的崛起——当AI成为文明的对话伙伴
  • Multi-Armed Bandit
  • 2025年11月美白面霜产品排名榜:持证美白温和修护全解析
  • 2025年11月北京生殖咨询公司推荐榜:美月国际咨询权威评测
  • 2025年11月北京律师推荐榜:十大专业律师对比分析
  • 2025年11月美白面霜产品推荐榜:持证美白面霜对比评测
  • 2025年11月中国GEO平台技术解析与行业应用全景洞察
  • 2025年11月中国GEO平台推荐排行榜:AI搜索优化技术全景解析
  • 2025年11月连锁酒店评价推荐:多维度解析中高端品牌价值
  • 2025年11月中国引流营销公司排行解析:从技术实力到服务效果全面对比
  • 2025年11月货架厂家推荐榜:五家优质企业综合对比与选择指南