专栏文章
题解:CF2144E1 Looking at Towers (easy version)
CF2144E1题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minvzm58
- 此快照首次捕获于
- 2025/12/02 09:15 3 个月前
- 此快照最后确认于
- 2025/12/02 09:15 3 个月前
- E1 容易先处理出 和 ,设元素个数分别为 。
接下来考虑 DP。设 表示前 个数选了 中的前 个数的方案; 表示后 个数选了 中的前 个数的方案。两者方程相似,故下面只对 进行讲解。
考虑转移,对于当前的数 ,以及 的前 个数已经被选择,可以分为以下三种情况:
-
若 在之前已经被选择,则 选不选均可,否则需要强制选,则有转移 。
-
的选择不会对 造成影响,则有转移 。
-
不能选择 ,否则会破坏 ,则有转移 。
当统计答案时,需要小心重复计算的情况。因此当 为全局最大值时,强制让 去选择这个最大值,然后强制 不选这个最大值,则对答案的贡献为 。
时间复杂度为 ,代码如下:
CPPvoid solve ()
{
int n = read (),mx = 0;
vector <int> a (n + 1),L (n + 1),R (n + 1);
vector <vector <int>> dp1 (n + 1,vector <int> (n + 1)),dp2 (n + 2,vector <int> (n + 2));
for (int i = 1;i <= n;++i) a[i] = read ();
int cntL = 0,cntR = 0;
for (int i = 1;i <= n;++i)
if (mx < a[i]) L[++cntL] = a[i],mx = a[i];
mx = 0;
for (int i = n;i;--i)
if (mx < a[i]) R[++cntR] = a[i],mx = a[i];
dp1[0][0] = dp2[n + 1][0] = 1;
for (int i = 1;i <= n;++i)
{
for (int j = cntL;~j;--j)
{
if (L[j] == a[i]) dp1[i][j] = (dp1[i - 1][j] * 2 % MOD + dp1[i - 1][j - 1]) % MOD;
else if (L[j] > a[i]) dp1[i][j] = dp1[i - 1][j] * 2 % MOD;
else dp1[i][j] = dp1[i - 1][j];
}
}
for (int i = n;i >= 1;--i)
{
for (int j = cntR;~j;--j)
{
if (R[j] == a[i]) dp2[i][j] = (dp2[i + 1][j] * 2 % MOD + dp2[i + 1][j - 1]) % MOD;
else if (R[j] > a[i]) dp2[i][j] = dp2[i + 1][j] * 2 % MOD;
else dp2[i][j] = dp2[i + 1][j];
}
}
ll ans = 0;
for (int i = 1;i <= n;++i)
{
if (a[i] != mx) continue;
ans = (ans + 1ll * ((dp1[i][cntL] - dp1[i - 1][cntL] + MOD) % MOD) * dp2[i + 1][cntR - 1] % MOD) % MOD;
}
printf ("%lld\n",ans);
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...