CF156C

Posted on 2026-07-26 14:03  K_J_M  阅读(6)  评论(0)    收藏  举报

很自然的将字符转化为数字,于是操作化为相邻两个一个加一一个减一,由于其和不变,于是又很容易猜测将总和分为 \(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;
}