首页 > 其他分享 >Solution - Atcoder AGC021D Reversed LCS

Solution - Atcoder AGC021D Reversed LCS

时间:2024-07-13 19:29:50浏览次数:6  
标签:Atcoder return LCS int Reversed maxn calc operatorname

考虑到 \(\operatorname{LCS}(T, T')\) 这个形式实在是不太优美,考虑转化一下形式。
感受一下,能够知道 \(T\) 的最长回文子序列 \(|\operatorname{LPS}(T)| = |\operatorname{LCS}(T, T')|\)。
具体证明可以见 zhihu,本人暂时还没看懂。

那么接下来对于单个串的 \(\operatorname{LPS}\) 就相对好求了。
考虑区间 DP,设 \(f_{l, r, k}\) 为此时处理到了前 \(l\) 个和第 \(r\) 个及之后,还能换 \(k\) 次的最优解。
那么转移就考虑两种情况:

  1. 不让 \(l, r\) 产生贡献,即 \(f_{l, r, k} \leftarrow \max\{f_{l + 1, r, k}, f_{l, r - 1, k}\}\)。
  2. 让 \(l, r\) 产生贡献,即 \(f_{l, r, k}\leftarrow f_{l + 1, r - 1, k - [s_l\not = s_r]} + 2\)。
    特殊的,有 \(f_{l, r, k} = -\infty(k < 0),f_{l, l, k} = 1\)。

时间复杂度 \(\mathcal{O}(|s|^3)\)。

#include<bits/stdc++.h>
const int maxn = 3e2 + 10;
char s[maxn];
int f[maxn][maxn][maxn], vis[maxn][maxn][maxn];
int calc(int l, int r, int k) {
   if (k < 0) return -1e9;
   if (l >= r) return l == r;
   if (vis[l][r][k]++) return f[l][r][k];
   return f[l][r][k] = std::max({calc(l + 1, r, k), calc(l, r - 1, k), calc(l + 1, r - 1, k - (s[l] != s[r])) + 2});
}
int main() {
   int k;
   scanf("%s%d", s + 1, &k);
   printf("%d\n", calc(1, strlen(s + 1), k));
   return 0;
}

标签:Atcoder,return,LCS,int,Reversed,maxn,calc,operatorname
From: https://www.cnblogs.com/rizynvu/p/18300519

相关文章

  • Solution - Atcoder ARC127E Priority Queue
    考虑转化一下,每个最后留下来的集合都相对的对应着一个被删除的集合。于是考虑去对被删除的数去计数。然后贪心的,去让每一次\(2\)操作删除的数都是前面加入中还剩下的最后加入的数(因为有的可能被前面的\(2\)操作删了)。对于证明,考虑到如果不是剩下的最后加入的,那么中间可能会......
  • 【atcoder】习题——位元枚举
    题意:求i&M的popcount的和,i属于0……N主要思路还是变加为乘。举个例子N=22,即10110假设M的第3位是1,分析N中:00110001110010000101发现其实等价于0010001100000001也就是左边第4位和第5位不变,右边第1位和第2位不变拼接起来,相当于0000~001101110011110110001101......
  • Solution - Atcoder ABC177F I hate Shortest Path Problem
    考虑按题目所述的进行DP。设计状态\(f_{i,j}\)代表强制要求\((i,j)\)要走向\((i+1,j)\)最小的横坐标之差,这是因为对应的纵坐标之差是确定的。对于转移,考虑到对于\(j\not\in[a_i,b_i]\),直接从上面转移下来即可,即\(f_{i,j}\leftarrowf_{i-1,j}\)。对于\(j......
  • Solution - Atcoder ARC150D Removing Gacha
    考虑到每次操作都比定会选上一个点,于是答案可以表示为每个点被选中的次数之和。即令\(c_i\)为\(i\)点被选中的次数,答案即为\(E(\sum\limits_{i=1}^nc_i)\)。根据期望的线性性,考虑把答案的\(E\)拆到每个\(c_i\)上,即变为\(\sum\limits_{i=1}^nE(c_i)\)的形式。......
  • Denso Create Programming Contest 2024(AtCoder Beginner Contest 361)E-F
    E求一条树上的路径,使得走遍整棵树花费最小。我们容易发现树上的某条简单路径只需走一次,除此之外所有的路径都需要走两次,那么显而易见,我们需要求树的直径,之后将剩余的路径权值和乘二加上直径权值就可以。F数学题,对于数学题而言,个人感觉时间复杂度的计算对于题目的求解非常重......
  • AtCoder Beginner Contest 361
    AtCoderBeginnerContest361A-Insert给定一个长度为\(N\)的序列\(A\),现在希望将数字\(X\)插入到序列的第\(K\)个数字后面,变成一个新的序列\(B\)。输出序列\(B\)。\(K,N,A_i,X\le100\)模拟题。先读入\(N,K,X\)。接着在读入\(A\)的过程中一遍读入一遍输出,如果读到了第\(K......
  • AtCoder Beginner Contest 361)
    推荐个C++编程仓库模板https://github.com/yxc-s/programming-templateA-Insertvoidsolve(){ intn,k,x; cin>>n>>k>>x; vector<int>a(n); for(auto&x:a){ cin>>x; } a.insert(a.begin()+k,x); for(inti=0;......
  • Denso Create Programming Contest 2024(AtCoder Beginner Contest 361)
    DensoCreateProgrammingContest2024(AtCoderBeginnerContest361)\(A\)Insert\(AC\)循环结构。点击查看代码inta[200];intmain(){intn,k,x,i;cin>>n>>k>>x;for(i=1;i<=n;i++){cin>>a[i];cout......
  • AtCoder Beginner Contest 361 补题记录(A~F)
    开题顺序:A-C-F-D-B-E。A直接模拟即可。boolbegmem;#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;classFastIO{public:intread(){into=1,x;charch;while(!isdigit(ch=getchar())){if......
  • Solution - Atcoder ARC125E Snack
    观察到这种都是数量上限的限制,且求\(\max\)。所以可以考虑网络流建模,而流量就对应着给的糖果数。令\(S\)为源点,\(T\)为汇点,编号为\(1\simn\)的点对应的糖果的种类,编号为\(n+1\simn+m\)的点对应的小孩。连边\((S,i,a_i)\),表示第\(i\)种糖果数不超过\(a_i\)......