题解:UVA11961 DNA
MaoTianLian · · 题解
题目分析
本题要求计算给定DNA序列通过最多
这题我们可以用动态规划(DP):使用二维DP数组
初始条件:
子问题定义:将问题分解为前
边界处理:当
时间复杂度为
代码实现
#include <iostream>
#include <set>
#include <string>
using namespace std;
int main() {
int T;
cin >> T;
while (T--) {
int N, K;
cin >> N >> K;
string dna;
cin >> dna;
set<string> mutations;
// 使用lambda表达式递归生成所有可能的变异序列c++11。
auto generate = [&](auto&& self, string cur, int pos, int changes) -> void {
if (pos == dna.size()) {
if (changes <= K) mutations.insert(cur);
return;
}
// 不改变当前字符
self(self, cur + dna[pos], pos + 1, changes);
// 尝试替换为其他三种字符
for (char c : {'A','C','G','T'}) {
if (c != dna[pos]) {
self(self, cur + c, pos + 1, changes + 1);
}
}
};
generate(generate, "", 0, 0);
cout << mutations.size() << '\n';
for (const auto& s : mutations) {
cout << s << '\n';
}
}
return 0;
}
代码注释
初始化DP数组:vector<vector<int>> dp(MAX, vector<int>(MAX, 0)) 创建一个二维数组,MAX为
填充DP数组:
外层循环遍历每个碱基位置
对于每个碱基,首先继承前一个碱基的方案数。然后遍历所有可能的替换碱基(A、C、G、T),若替换碱基与当前碱基不同,则累加前一个碱基的方案数(替换一次)。
计算最终答案:遍历所有替换次数