Codeforces Round #570 (Div. 3)
dp[i][j]表示使用前j个字符构成的长为i的distinct子串个数
状态转移方程:
dp[i][j]=dp[i-1][j-1]+dp[i][j-1]
如果当前字符已经出现过,要减去最近此字符的之前的长度-1的distinct子串个数:dp[i-1][last-1]
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll dp[105][105];
int main(){
ll n,k;
cin>>n>>k;
string s;
cin>>s;
fill(dp[0],dp[0]+n+5,1);
for(int i=1;i<=n;i++){
map<int,int> ma;
ma.clear();
for(int j=i;j<=n;j++){
dp[i][j]=dp[i-1][j-1]+dp[i][j-1];
if(ma[s[j-1]]!=0){
// cout<<ma[s[j-1]]<<endl;
dp[i][j]-=dp[i-1][ma[s[j-1]]-1];
}
ma[s[j-1]]=j;
}
}
ll sum=0;
ll ans=0;
int i;
for(i=n;i>=0;i--){
sum+=dp[i][n];
if(sum>=k){
ans+=(n-i)*(dp[i][n]-sum+k);
break;
}
ans+=(n-i)*dp[i][n];
}
if(i!=-1)
cout<<ans<<endl;
else {
cout<<i<<endl;
}
return 0;
}