题解:P9640 [SNCPC2019] Digit Mode
思路
定义
首先类似数位 DP,枚举有
这时我们枚举出现次数最多的数是
而最终对答案的贡献为
最终复杂度为
代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod = 1e9+7,N = 100;
int a[N],C[N][N],f[N],cnt,add[N],ans;
string s;
inline void work(int len)
{
for(int c = 0;c<=9;c++) for(int m = add[c];m<=add[c]+len;m++)
{
int tot = len-(m-add[c]);
for(int i = 0;i<=tot;i++) f[i] = 0;
f[0] = 1;
bool fl = 1;
for(int i = 0;i<=9;i++)
{
if(i==c) continue;
int lim = m-add[i];
if(i>c) lim--;
if(lim<0)
{
fl = 0;
break;
}
for(int j = tot;j;j--)
for(int k = 1;k<=min(lim,k);k++)
(f[j]+=f[j-k]*C[j][k])%=mod;
}
if(fl) (ans+=f[tot]*c*C[len][m-add[c]])%=mod;
}
}
inline void solve()
{
cin>>s,cnt = s.size();
for(int i = 1;i<=cnt;i++)
a[i] = s[i-1]-'0';
for(int i = 0;i<=9;i++) add[i] = 0;
for(int i = 1;i<=cnt;i++)
add[a[i]]++;
ans = 9;
for(int i = 8;~i;i--)
if(add[i]>add[ans]) ans = i;
for(int i = 0;i<=9;i++) add[i] = 0;
for(int i = 1;i<cnt;i++)
{
for(int j = 1;j<=9;j++)
add[j]++,work(i-1),add[j]--;
}
for(int i = 1;i<=cnt;i++)
{
int mn = 1;
if(i!=1) mn = 0;
for(int j = mn;j<a[i];j++)
add[j]++,work(cnt-i),add[j]--;
add[a[i]]++;
}
cout<<ans<<'\n';
}
signed main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
C[0][0] = 1;
for(int i = 1;i<N;i++)
{
C[i][0] = 1;
for(int j = 1;j<=i;j++)
C[i][j] = (C[i-1][j]+C[i-1][j-1])%mod;
}
int T;cin>>T;
while(T--) solve();
return 0;
}