Solution -「JOISC 2020」建筑装饰 4

solution,joisc,建筑,装饰 · 浏览次数 : 5

小编点评

```c++ #include #include #include #include using namespace std; const int N = 1e6; int n, a[N + 100], b[N + 100], f[N + 100][2][2]; char ans[N + 100]; int main(){ ios::sync_with_stdio(0); cin.tie(nullptr); rd(n), rds(a, 2 * n) , rds(b, 2 * n); // Initialize DP table for (int i = 0; i < 2 * n; i++) { for (int j = 0; j < 2; j++) { f[i][j][0] = f[i - 1][j][0]; f[i][j][1] = f[i - 1][j][1]; } } // Fill in DP table for (int i = 1; i < 2 * n; i++) { if (a[i] >= a[i - 1]) { chkmax(f[i][A][A], f[i - 1][A][A] + 1); chkmax(f[i][A][B], f[i - 1][A][B]); } if (a[i] >= b[i - 1]) { chkmax(f[i][A][A], f[i - 1][B][A] + 1); chkmax(f[i][A][B], f[i - 1][B][B]); } if (b[i] >= a[i - 1]) { chkmax(f[i][B][B], f[i - 1][A][B] + 1); chkmax(f[i][B][A], f[i - 1][A][A]); } if (b[i] >= b[i - 1]) { chkmax(f[i][B][B], f[i - 1][B][B] + 1); chkmax(f[i][B][A], f[i - 1][B][A]); } } int cnt[2] = {}, last = 1e9; drep (i, 2 * n, 1) { if (cnt[A] + f[i][A][A] >= n && cnt[B] + f[i][A][B] >= n && a[i] <= last) last = a[i], ans[i] = 'A', cnt[A]++; else if (cnt[A] + f[i][B][A] >= n && cnt[B] + f[i][B][B] >= n && b[i] <= last) last = b[i], ans[i] = 'B', cnt[B]++; else { cout << \"-1\\"; return 0; } } copy_n(ans + 1, 2 * n, ostream_iterator<char>(cout, \"\")); } ```

正文

  朴素的 DP 形式是定义 \(f_{i, j, A/B}\) 表示前 \(i\) 个元素选择了 \(j\)\(A\) 的可达性. \(\mathcal O(n^2)\). 交换状态与值域, 定义 \(f_{i, A/B, A/B}\) 表示前 \(i\) 个元素中的最后一个元素 (即 \(i\)) 选择了 \(A/B\), 在最大化 \(A/B\) 的数量的目标下求得的 \(A/B\) 的数量.

  转移在代码注释里, 答案倒着构造.

/**
 * dp[i][A/B][A/B]: 前 i 个, 第 i 个选 A 还是 B, 最大化 A/B 的数量
 * a[i] >= a[i-1]: dp[i-1][A][A]+1 -> dp[i][A][A]; dp[i-1][A][B] -> dp[i][A][B]
 * a[i] >= b[i-1]: dp[i-1][B][A]+1 -> dp[i][A][A]; dp[i-1][B][B] -> dp[i][A][B]
 * b[i] >= a[i-1]: dp[i-1][A][B]+1 -> dp[i][B][B]; dp[i-1][A][A] -> dp[i][B][A]
 * b[i] >= b[i-1]: dp[i-1][B][B]+1 -> dp[i][B][B]; dp[i-1][B][A] -> dp[i][B][A]
*/
enum Element {A, B};
const int N = 1e6;
int n, a[N + 100], b[N + 100], f[N + 100][2][2];
char ans[N + 100];
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(nullptr);
    rd(n), rds(a, 2 * n) , rds(b, 2 * n);
    rep (i, 1, 2 * n) {
        if (a[i] >= a[i - 1]) {
            chkmax(f[i][A][A], f[i - 1][A][A] + 1);
            chkmax(f[i][A][B], f[i - 1][A][B]);
        }
        if (a[i] >= b[i - 1]) {
            chkmax(f[i][A][A], f[i - 1][B][A] + 1);
            chkmax(f[i][A][B], f[i - 1][B][B]);
        }
        if (b[i] >= a[i - 1]) {
            chkmax(f[i][B][B], f[i - 1][A][B] + 1);
            chkmax(f[i][B][A], f[i - 1][A][A]);
        }
        if (b[i] >= b[i - 1]) {
            chkmax(f[i][B][B], f[i - 1][B][B] + 1);
            chkmax(f[i][B][A], f[i - 1][B][A]);
        }
    }
    int cnt[2] = {}, last = 1e9;
    drep (i, 2 * n, 1) {
        if (cnt[A] + f[i][A][A] >= n && cnt[B] + f[i][A][B] >= n && a[i] <= last) last = a[i], ans[i] = 'A', cnt[A]++;
        else if (cnt[A] + f[i][B][A] >= n && cnt[B] + f[i][B][B] >= n && b[i] <= last) last = b[i], ans[i] = 'B', cnt[B]++;
        else {
            cout << "-1\n"; return 0;
        }
    }
    copy_n(ans + 1, 2 * n, ostream_iterator<char>(cout, ""));
}

与Solution -「JOISC 2020」建筑装饰 4相似的内容:

Solution -「JOISC 2020」建筑装饰 4

朴素的 DP 形式是定义 \(f_{i, j, A/B}\) 表示前 \(i\) 个元素选择了 \(j\) 个 \(A\) 的可达性. \(\mathcal O(n^2)\). 交换状态与值域, 定义 \(f_{i, A/B, A/B}\) 表示前 \(i\) 个元素中的最后一个元素 (即 \(i\

Solution -「HDU」Ridiculous Netizens

Desc. 给定一棵 \(N\) 个节点无根树,找出满足以下条件的集合 \(S\) 的数量: \(S \subseteq \{1,\dots,n\}\); \(S\) 的导出子图联通; \(\displaystyle\prod_{v \in S} a_v \leqslant M\)。 Sol. 点分

Solution -「模拟赛」草莓蛋糕

\(\max(a_x + a_y, b_y + b_x)\) 的贡献形式不是独立的,并不好进行分析。考虑通过分类讨论将 \(\max\) 拆开。若令 \(h_i = a_i - b_i\),\(h'_i = b_i - a_i\),可以发现若 \(h_x \geqslant h'_y\) 取值则为

Solution -「ARC 106E」Medals

Desc. Link. 你有 \(n\) 个朋友,他们会来你家玩,第 \(i\) 个人 \(1...A_i\) 天来玩,然后 \(A_i+1...2A_i\) 天不来,然后 \(2A_i+1...3A_i\) 又会来,以此类推; 每天你会选一个来玩的人,给他颁个奖,如果没人来玩,你就不颁奖。 你要给

Solution -「LOJ #3310」丁香之路

首先有两个前置技巧:1) 两点间的最短距离就是直接连接两点的边的长度;2) 遍历一个子图的最小花费是最小生成树的边权之和乘二。原问题让我们找出一条最短且必经过钦定边的 \(( s, i )\) 路径,那么我们先将 \(\lang s , i \rang\) 连上,问题就变成了找出一条最短且必经过钦定

MetaTown:一个可以自己构建数字资产的平台

摘要:华为云Solution as Code重磅推出《基于MetaTown构建数字资产平台》解决方案。 本文分享自华为云社区《基于MetaTown构建数字资产平台》,作者: 阿米托福。 华为云Solution as Code重磅推出《基于MetaTown构建数字资产平台》解决方案,由华为云数字资产链

带你了解基于Ploto构建自动驾驶平台

摘要:华为云Solution as Code推出基于Ploto构建自动驾驶平台解决方案。 本文分享自华为云社区《基于Ploto构建自动驾驶平台》,作者:阿米托福 。 2022年6月15日,主题为“因聚而生 为你所能”的华为伙伴暨开发者大会 2022 正式开启,在自动驾驶专场中,华为云携手合作伙伴联合

pbjs 无法编码 bytes 类型数据问题的解决方案

一段包含 bytes 类型的 protobuf 二进制数据,经过 pbjs 解码生成的 json 文件,再传递给 pbjs 编码后生成的二进制数据和原始数据差异巨大,经过一番探究,发现居然是 pbjs 的一个 bug,快来看看你是否踩过这个坑吧~

拯救SQL Server数据库事务日志文件损坏的终极大招

拯救SQL Server数据库事务日志文件损坏的终极大招 在数据库的日常管理中,我们不可避免的会遇到服务器突然断电(没有进行电源冗余),服务器故障或者 SQL Server 服务突然停掉, 头大的是ldf事务日志文件也损毁了,SQL Server服务器起来之后,发现数据库处于"Recovery Pe