H. Subsequences (hard version)

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
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 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<=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<

 

你可能感兴趣的:(H. Subsequences (hard version))