如果想到了的话,这题就不难了。
首先解决一个简单的问题,如何求出串有多少不同的子序列
定义为以
的长度为
的子序列个数
,意思是选或者不选
都是一种选择
但是有重复,考虑且
时
形成的子序列后面接上
或者接上
是等价的
所以真正的转移方程是
也就是找到最近的一个满足条件的,然后去掉
的方案数
那么这题就简单了..
这样处理出数组去贪心即可得到解
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 109;
int n,k,pre[maxn],f[maxn][maxn],ans;
char a[maxn];
signed main()
{
cin >> n >> k >> ( a+1 );
f[0][0] = 1;
for(int i=1;i<=n;i++)
{
f[i][0] = 1;
for(int j=1;j<=i;j++)
{
f[i][j] += f[i-1][j-1]+f[i-1][j];
if( pre[a[i]-'a'] ) f[i][j] -= f[pre[a[i]-'a']-1][j-1];
if( f[i][j]>k ) f[i][j] = k;
}
pre[a[i]-'a'] = i;
}
for(int i=n;i>=0;i--)
{
int x = min( k,f[n][i] );
k -= x;
ans += x*(n-i);
}
if( k ) ans = -1;
cout << ans;
} 
京公网安备 11010502036488号