AtCoder Regular Contest 128(补题)

Posted 佐鼬Jun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoder Regular Contest 128(补题)相关的知识,希望对你有一定的参考价值。

D - Neq Neq

链接: link.

题意:

给一个长度为 N N N的序列, A i , A 2 . . . . . A n A_i,A_2.....A_n Ai,A2.....An,现在可以删除一些数,删除的原则是,三个相邻的数, A x , A y , A z A_x,A_y,A_z Ax,Ay,Az,可以删除 A y A_y Ay,问能形成多少种序列,序列不同,只要里面有一个数的下标不同,就算序列不同。

思路:

f ( i ) f(i) f(i)代表以第 i i i个数为结尾的序列方案数
那么此时想要求出 f ( i ) f(i) f(i),序列无论是何种情况,都可以继承 i − 1 i-1 i1的方案序列,就相当于以第 i − 1 i-1 i1个数为结尾形成的序列之后再加一个数 A i A_i Ai
如果此时 A i = A i − 2 且 A i ! = A i − 1 A_i=A_{i-2}且A_i!=A_{i-1} Ai=Ai2Ai!=Ai1,此时,可以把 A i − 1 A_{i-1} Ai1这个数删了,然后以 A i − 2 A_{i-2} Ai2为结尾的序列,在后面放 A i A_i Ai,所以就相当于 A i A_i Ai继承了 A i − 2 A_{i-2} Ai2的方案序列
此时如果 i i i之前出现了,一段序列的数是不相同的情况,即 A j 和 A j − 1 A_j和A_{j-1} AjAj1不相同的一段连续序列,那么此时 f ( i ) f(i) f(i)此时就可以继承这段的序列方案,就例如 a a a a c d e a b a aaaacdeaba aaaacdeaba,[1234…8 9 10]因为 ~~里面的数都不相同,pos2的位置定在3,pos1定在8,就可以在先删除b再删除a后,形成 a a a a c d e a aaaacdea aaaacdea,继承以 e e e为结尾的序列方案数,再删除e,然后再以 d d d为结尾的序列,一直到a为止。所以,就需要 p o s 1 和 p o s 2 pos1和pos2 pos1pos2,pos2标记最近的出现 A j 和 A j − 1 A_j和A_{j-1} AjAj1相同的位置,然后pos1,记录的位置是最近出现 A j 和 A j − 2 A_j和A_{j-2} AjAj2不相同的位置,因为只有当 A j 和 A j − 2 A_j和A_{j-2} AjAj2 A j 和 A j − 1 A_j和A_{j-1} AjAj1,这样就可以删除 A j − 1 和 A j − 2 A_{j-1}和A_{j-2} Aj1Aj2这两个数了

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 10;
const int mod = 998244353;

int a[N];
int dp[N], sum[N];
int n;

signed main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    dp[1] = 1, sum[1] = 1;
    int pos1 = 0, pos2 = 0;
    for (int i = 2; i <= n; i++) {
        (dp[i] += dp[i - 1]) %= mod;
        if (a[i] == a[i - 2] && a[i] != a[i - 1] && i >= 3) {
            (dp[i] += dp[i - 2]) %= mod;
        }
        if (a[i] == a[i - 1]) {
            pos2 = i - 1;
        }
        if (a[i] != a[i - 2] && i >= 3) {
            pos1 = i - 2;
        }
        if (pos1 > pos2) {
            (dp[i] += (sum[pos1] - sum[pos2] + mod) % mod) %= mod;
        }
        sum[i] = (sum[i - 1] + dp[i]) % mod;
    }
    cout << dp[n] << endl;
}

C - Max Dot

链接: link.

题意:

N , M , S N,M,S N,M,S三个数字, A 1 . . . . A n A_1....A_n A1....An序列长度为n,让做一个 B 1 . . . B n B_1...B_n B1...Bn序列,序列 B 1 . . . B n B_1...B_n B1...Bn,满足两个条件 B 1 < = B 2 < = B 3 . . . . < = B n < = M B_1<=B_2<=B_3....<=B_n<=M B1<=B2<=B3....<=Bn<=M ∑ i = 1 n B i \\sum \\limits_{i=1} ^{n}Bi i=1nBi = = =S,现在让你使 ∑ i = 1 n A i ∗ B i \\sum \\limits_{i=1} ^{n}A_i*B_i i=1nAiBi最大,然后输出最大值。

思路:

在没有所有数 < = M <=M <=M这个条件下,可以引入一个后缀性价比的概念,即后缀和 s u f ( i ) suf(i) suf(i),然后求性价比最高的一个后

以上是关于AtCoder Regular Contest 128(补题)的主要内容,如果未能解决你的问题,请参考以下文章

刷题AtCoder Regular Contest 001

AtCoder Regular Contest 094

[Atcoder Regular Contest 060] Tutorial

AtCoder Regular Contest 103

AtCoder Regular Contest 128

AtCoder Regular Contest 119 C