日常刷题2025-2-15

日常刷题2025-2-15

智乃与长短期主义者博弈

rating:299/963

https://ac.nowcoder.com/acm/contest/101918/D

思路:区间DP

为了避免特殊情况,思考问题时应该思考更加一般的中间状态。题目描述是有几种操作,让你根据情况选择最优的操作,看到这种题面一般就是两种做法,要么贪心要么DP。此题贪心要考虑的问题太多,所以直接DP暴力的看每一种选择。同时一看数据范围 \(10^3\) 也可以判断大概率是DP。

代码

#include <bits/stdc++.h>

using i64 = long long;
using u64 = unsigned long long;

typedef std::pair<long long, long long> PII;
const int mod = 998244353;
const int N = 2e6 + 1000;
const int INF = 0x3f3f3f3f;
const long long LINF = 1e18;
const double eps = 1e-12;
const double pi = std::acos(-1);
std::mt19937_64 rnd(std::chrono::steady_clock::now().time_since_epoch().count());
std::uniform_int_distribution<u64> dist_rand(mod / 2, mod - 1);

void solve() {
    int n;
    std::cin >> n;
    std::vector<int> a(n + 1);
    std::vector dp(n + 1, std::vector<int>(n + 1));
    for (int i = 1; i <= n; i++) std::cin >> a[i];
    int sum = std::accumulate(a.begin(), a.end(), 0);
    
    for (int i = 1; i <= n; i++) dp[i][i] = 0;
    for (int i = 1; i < n; i ++) dp[i][i + 1] = std::min(a[i], a[i + 1]);

    for (int len = 3; len <= n; len ++)
        for (int l = 1; l + len - 1 <= n; l ++) {
            int r = l + len - 1;
            if (a[l] >= a[r]) {
                dp[l][r] = std::max(dp[l + 2][r] + a[l + 1], dp[l + 1][r - 1] + a[r]);
            } else {
                dp[l][r] = std::max(dp[l + 1][r - 1] + a[l], dp[l][r - 2] + a[r - 1]);
            }
        }

    std::cout << sum - dp[1][n] << " " << dp[1][n] << "\n";
}

signed main() {
    std::ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);
    
    int tmp = 1;
    
    // std::cin >> tmp;

    while (tmp--)
        solve();

    return 0;
}

智乃的数组乘积

rating:39/293

https://ac.nowcoder.com/acm/contest/101918/F

思路:经典双指针

固定一个端点,枚举另一个端点。注意零在其中产生的关键作用。想不出思路可以推推题目中出现的式子。

代码

#include <bits/stdc++.h>

using u64 = unsigned long long;
using i64 = long long;
typedef std::pair<int, int> pii;
const int mod = 998244353;
const long long LINF = 1e18;

i64 expit(i64 a, i64 b, i64 p){
    i64 res = 1;
    while (b){
        if (b & 1) res = res * a % p;
        a = a * a % p;
        b >>= 1;
    }
    return res;
}

void solve(){
    i64 n, p, x;
    std::cin >>n >> p >> x;

    std::vector<i64> a(n+1);
    for (int i = 1; i <= n; i++) std::cin >> a[i];

    if (x == 0) {
        for (int i = 1; i <= n; i ++) std::cout << (!a[i] ? 1 : a[i]) << " ";
        return ;
    }

    i64 invx = expit(x, p-2, p);
    for (int l = 1, r; l <= n; l = r + 1){
        r = l;

        i64 mul = 1;
        std::map<i64, int> mp;
        mp[1] = true;

        while (r <= n && !mp.contains(mul * a[r] % p * invx % p) && a[r] != 0){
            mul = (mul * a[r]) % p;
            mp[mul] = true;
            r++;
        }

        if (r > n) break;
        a[r] = 0;
    }

    for (int i = 1; i <= n; i++) std::cout << a[i] << ' ';
}

signed main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(15);

    int t = 1, i;
    for (i = 0; i < t; i++){
        solve();
    }

    return 0;
}
posted @ 2025-02-15 14:36  califeee  阅读(18)  评论(0)    收藏  举报