牛客练习赛60 C 操作集锦

思路:

用dp,比赛的时候完全没想到dp,太难受了,其实是一道基础dp;注意的地方当pre[s[i]-'a']不为0时,更新dp[i][j]的时候要+mod,这个会卡20%的数据,

代码:

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
const int mod =1e9+7;
const int maxn = 1e3+5; 
int dp[maxn][maxn];
int pre[maxn];
int main(){
    int n,k;
    cin>>n>>k;
    char s[1005];
    cin>>(s+1);
    memset(dp,0,sizeof(dp));
    memset(pre,0,sizeof(pre));
    dp[0][0] = 1;
    for(int i=1;i<=n;i++){
        dp[i][0] = 1;
        for(int j=1;j<=i;j++){
            dp[i][j] = (dp[i-1][j-1]+dp[i-1][j])%mod;
            if(pre[s[i]-'a']) dp[i][j]=(dp[i][j]-dp[pre[s[i]-'a']-1][j-1]+mod)%mod;//减去上一次出现的该字母与该字母之前的字母的组合,而不是dp[pre[s[i]-'a'][j]:这个就把该字母之前的字母组成的j个字母全都去掉了
        }
        pre[s[i]-'a'] = i;
    }
    cout<<dp[n][k]%mod<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/lusiqi/p/12634716.html