【DP】CF156C
一开始想了一个复杂度爆炸的 DP
分析
首先考察题目的性质:
方便起见,将字符看成是 的值。
注意到操作可以等价于选择任意两个下标,然后对应的两个值一加一减或者一减一加。
这样的操作显然不会改变字符串的值和(也就是字符串中每个字符对应的值的和)
进一步地,可以发现答案就是与当前字符串值和(记为 )相等的字符串个数(当然因为当前字符串本身不计入,所以答案即为所有合法且值和为 的字符串个数 - 1)
这里合法字符串就是每个字符为小写字符的字符串。
考虑 DP 求解:
记长 个字符,值和为 的合法字符串有 个。
那么有转移:,其中 且 。
// Problem: Cipher
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/CF156C
// Memory Limit: 250 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using namespace std;
#define debug(x) cerr << #x << ": " << (x) << endl
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define x first
#define y second
using pii = pair<int, int>;
using ll = long long;
inline void read(int &x){
int s=0; x=1;
char ch=getchar();
while(ch<'0' || ch>'9') {if(ch=='-')x=-1;ch=getchar();}
while(ch>='0' && ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
x*=s;
}
const int N=110, mod=1e9+7;
int f[N][2605];
int add(int x, int y){
return x+y>=mod? x+y-mod: x+y<0? x+y+mod: x+y;
}
void init(){
f[0][0]=1;
rep(i, 1, 100){
rep(j, 0, 2600){
rep(c, 0, 25){
if(j-c>=0) f[i][j]=add(f[i][j], f[i-1][j-c]);
}
}
}
}
void solve(){
string s; cin>>s;
int n=s.size();
int val=0;
for(auto i: s) val+=(i-'a');
cout<<add(f[n][val], -1)<<endl;
}
signed main(){
init();
int cs; cin>>cs;
while(cs--) solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探