很自然的将字符转化为数字,于是操作化为相邻两个一个加一一个减一,由于其和不变,于是又很容易猜测将总和分为 \(n\) 个 \([0,25]\) 以内的数字组成的字符串一定可以由原字符串经过如上操作得到,即二者等价。考虑 \(dp_{i,j}\) 表示前 \(i\) 个分配和为 \(j\) 时的方案数,于是 \(dp_{i,j}= \sum dp_{i-1,k}\),时间复杂度为 \(\mathcal O(T26^2n^2)\) ,明显超时,注意到答案与字符串无关,只与其对应的和相关,于是预处理即可。
\(\texttt {code}\)
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e2+10;
const int mod = 1e9+7;
int t,n,dp[N][30*N];
string s;
signed main(){
cin>>t;
dp[0][0]=1;
for(int i=1;i<=100;++i){
for(int j=0;j<=2500;++j){
for(int k=0;k<=min(25ll,j);++k){
(dp[i][j]+=dp[i-1][j-k])%=mod;
}
}
}
while(t--){
cin>>s;
n=s.size();
int sum=0;
for(auto it:s)sum+=it-'a';
cout<<dp[n][sum]-1<<"\n";
}
return 0;
}
浙公网安备 33010602011771号