牛客练习赛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;
}