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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章