C++程序:查找给定字符串中k个唯一子序列后的成本
假设我们有一个字符串s和另一个值k。我们必须选择s的一些子序列,以便我们可以得到k个唯一的子序列。这里,选择子序列的成本等于s的长度 - 子序列的长度。因此,我们必须找到在选择k个唯一子序列后可能的最低总成本。如果我们无法找到这个集合,我们将返回-1。我们将空字符串视为有效的子序列。
因此,如果输入类似于s = "pqrs",k = 4,则输出将为3。
为了解决这个问题,我们将遵循以下步骤:
n := s的长度
定义一个大小为(n + 1) x (n + 1)的二维数组dp,并将其初始化为0
定义一个映射last
dp[0, 0] := 1
初始化i := 0,当i < n时,更新(i递增1),执行:
dp[i + 1, 0] := 1
初始化j := (i + 1),当j >= 1时,更新(j递减1),执行:
dp[i + 1, j] := dp[i, j] + dp[i, j - 1]
如果s[i]不是last的末尾元素,则:
初始化j := 0,当j <= last[s[i]]时,更新(j递增1),执行:
dp[i + 1, j + 1] -= dp[last[s[i]], j]
last[s[i]] := i
cost := 0
初始化i := n,当i >= 0时,更新(i递减1),执行:
val := k和dp[n, i]的最小值
cost := cost + (val * (n - i))
k := k - dp[n, i]
如果k <= 0,则:
退出循环
如果k <= 0,则:
返回cost
返回-1
示例
让我们看看下面的实现以更好地理解:
#include <bits/stdc++.h>
using namespace std;
int solve(string s, int k) {
int n = s.size();
vector<vector<int>> dp(n + 1, vector<int>(n + 1, 0));
unordered_map<char, int> last;
dp[0][0] = 1;
for (int i = 0; i < n; i++) {
dp[i + 1][0] = 1;
for (int j = (i + 1); j >= 1; j--) {
dp[i + 1][j] = dp[i][j] + dp[i][j - 1];
}
if (last.find(s[i]) != last.end()) {
for (int j = 0; j <= last[s[i]]; j++) {
dp[i + 1][j + 1] -= dp[last[s[i]]][j];
}
}
last[s[i]] = i;
}
int cost = 0;
for (int i = n; i >= 0; i--) {
int val = min(k, dp[n][i]);
cost += (val * (n - i));
k -= dp[n][i];
if (k <= 0) {
break;
}
}
if (k <= 0) {
return cost;
}
return -1;
}
int main(){
cout << solve("pqrs",4) << endl;
return 0;
}输入
"pqrs", 4
输出
3
广告
数据结构
网络
关系数据库管理系统 (RDBMS)
操作系统
Java
iOS
HTML
CSS
Android
Python
C语言编程
C++
C#
MongoDB
MySQL
Javascript
PHP