牛オフ練習試合60 C.業績ハイライト

リンク
の問題の意味:
求めている文字列 \(S \)の異なる配列の数の
アイデア:
設定 \(DP [I、J]は \) フロントです \(I \)の長さの文字 \(J \)異なる配列の数で
繰り返されているとはみなされない: \([1-I、J] [1-I、J-1] F [I、J] = F + Fは、\)
減算検討します繰り返しサブ:場合に見出すことができる \(I \)の前に存在する(S [I] \)\この文字の、この位置が提供される \(T \) 長さ \(J \) \(T \)シーケンスの終了 \(F [I、J] \) 、繰り返される部分は2倍を算出した(F [T-1] \
[J-1] \) このようにして記録時の \(I \)最初の前に \(S [I] \)それらが現れ、繰り返すことができる部分が減算される
注:長さのこの質問 \(0 \)有効なシーケンスである
コード:

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
typedef long long ll;
typedef pair<int,int> pii;
 
const ll mod=1e9+7;
const int N=1010;
char s[N];
ll dp[N][N];
int pre[30];
int main() {
    //freopen("in.txt","r",stdin);
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n,k;
    cin>>n>>k;
    cin>>s+1;
    dp[0][0]=1;
    for(int i=1;i<=n;i++) {
        dp[i][0]=1;
        for(int j=1;j<=min(i,k);j++) {
            dp[i][j]=(dp[i-1][j]+dp[i-1][j-1])%mod;
            if(pre[s[i]-'a']) dp[i][j]=(dp[i][j]+mod-dp[pre[s[i]-'a']-1][j-1])%mod;
        }
        pre[s[i]-'a']=i;
    }
    cout<<dp[n][k]<<endl;
    return 0;
}

おすすめ

転載: www.cnblogs.com/c4Lnn/p/12596110.html