P1410 子序列(思维 + 类背包)

题目连接:https://www.luogu.com.cn/problem/P1410

参考文章:https://www.luogu.com.cn/blog/XTZORZ/solution-p1385

思路:

重点就是不同长度产生的字符串的个数和字符串的所有字符权值之和有关,因为每次变换都不影响最终字符串的权值之和。

所以预处理长度为i,权值之和为j的字符串产生的字符串的个数就好了,dp[i,j]表示长度为i,字符串权值之和为j的字符串产生的字符串的个数,注意,最终求出的结果要-1,因为不包含自己。

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
char ss[120];
ll dp[105][3003] = {0};
int main(void)
{
    int n,T;
    for(int i=0;i<26;i++) dp[1][i] = 1;
    for(int i=2;i<=102;i++)
    {
        dp[i][0] = 1;
        for(int j=1;j<=2700;j++)
            for(int k=0;k<26 && k<=j;k++)
            dp[i][j] = (dp[i][j] + dp[i-1][j-k]%mod)%mod;
    }
    scanf("%d",&T);
    while(T--)
    {
        scanf("%s",ss);
        n = strlen(ss);
        int sum = 0;
        for(int i=0;i<n;i++) sum += (ss[i] - 'a');
        ll ans = dp[n][sum] - 1;
        printf("%lld\n",(ans%mod+mod)%mod);
    }
    return 0;
}
发布了438 篇原创文章 · 获赞 16 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_41829060/article/details/104068338