D. Shortest and Longest LIS
发布日期:2021-05-08 16:30:19 浏览次数:20 分类:精选文章

本文共 1729 字,大约阅读时间需要 5 分钟。

为了解决这个问题,我们需要根据给定的比较符号生成两个数列:一个数列的上升子序列最短,另一个数列的上升子序列最长。我们可以通过解析比较符号来构建一个有序的序列,然后根据这个序列生成两个数列。

方法思路

  • 解析比较符号:将输入的比较符号转换为一种图结构,其中每个节点代表一个元素,边表示元素之间的顺序关系。
  • 拓扑排序:使用Kahn算法进行拓扑排序,生成一个线性序列,确保满足所有比较关系。
  • 生成数列
    • 第一个数列:逆序排列拓扑顺序,生成一个递减的数列,使得其上升子序列最短。
    • 第二个数列:直接使用拓扑顺序生成一个递增的数列,使得其上升子序列最长。
  • 解决代码

    #include 
    #include
    #include
    #include
    using namespace std;void topo_sort(int n, vector
    >& graph, vector
    & in_degree) { queue
    q; vector
    order; for (int i = 0; i < n; ++i) { if (in_degree[i] == 0) { q.push(i); } } while (!q.empty()) { int u = q.front(); q.pop(); order.push_back(u); for (int v : graph[u]) { in_degree[v]--; if (in_degree[v] == 0) { q.push(v); } } } return order;}void solve() { int t, n; string s; cin >> t; for (int _ = 0; _ < t; ++_) { cin >> n; cin >> s; vector
    > graph(n); vector
    in_degree(n, 0); for (int i = 0; i < s.size(); ++i) { char c = s[i]; int u = i; int v = i + 1; if (c == '<') { graph[u].push_back(v); in_degree[v]++; } else if (c == '>') { graph[u].push_back(v); in_degree[v]++; } } vector
    order = topo_sort(n, graph, in_degree); vector
    first(n); for (int i = 0; i < n; ++i) { first[i] = order[n - 1 - i]; } vector
    second(n); for (int i = 0; i < n; ++i) { second[i] = order[i]; } for (int num : first) { cout << num + 1 << ' '; } cout << '\n'; for (int num : second) { cout << num + 1 << ' '; } cout << '\n'; }}int main() { solve(); return 0;}

    代码解释

  • 拓扑排序函数:使用Kahn算法对图进行拓扑排序,生成一个线性序列。
  • 主解析函数:读取输入,解析比较符号,构建图和入度数组,然后进行拓扑排序。
  • 生成数列:根据拓扑顺序生成两个数列,第一个数列逆序排列,第二个数列直接使用拓扑顺序。
  • 输出结果:打印两个数列。
  • 这种方法确保了第一个数列的上升子序列最短,第二个数列的上升子序列最长,满足题目的要求。

    上一篇:21.4.周末总结(第六次)
    下一篇:FatMouse‘s Speed

    发表评论

    最新留言

    网站不错 人气很旺了 加油
    [***.192.178.218]2025年05月22日 12时55分52秒