zoukankan      html  css  js  c++  java
  • CF1542D

    题目

    source

    题解

    直接计算似乎十分困难,那么可以单独考虑每个数x的贡献。(B_x)为最后(x)存在于队列中的方案数,那么答案就是(sum{x imes B_x})
    对于每条类型2的指令I,假设它的值为X,它的方案数可以用dp计算得到。令dp[i][j]代表在第i条指令时队列内比X小的数有j个时的方案数。在比较大小时用位置作为第二关键字,再特判i==I时的转移方程,这样就只有大于和小于两种情况,不会算漏。

    细节详见代码

    #include <bits/stdc++.h>
     
    #define endl '
    '
    #define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
    #define mp make_pair
    #define seteps(N) fixed << setprecision(N) 
    typedef long long ll;
     
    using namespace std;
    /*-----------------------------------------------------------------*/
     
    ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
    #define INF 0x3f3f3f3f
    const int N = 510;
    const int M = 998244353;
     
    ll dp[N][N];
    ll arr[N];
    bool flag[N];
     
    int main() {
        IOS;
        int n;
        cin >> n;
        for(int i = 1; i <= n; i++) {
            char ch;
            cin >> ch;
            if(ch == '-') {
                flag[i] = true;
            } else {
                cin >> arr[i];
            }
        }
        ll ans = 0;
        for(int I = 1; I <= n; I++) {
            if(flag[I]) continue;
            memset(dp, 0, sizeof dp);
            dp[0][0] = 1;
            ll V = arr[I];
            for(int i = 1; i <= n; i++) {
                if(flag[i]) {
                    for(int j = 0; j <= i; j++) {
                        dp[i][j] = (dp[i - 1][j] + dp[i - 1][j + 1]) % M;
                        if(j == 0) dp[i][j] += dp[i - 1][j];
                        dp[i][j] %= M;
                    }
                } else if(i == I) {
                    for(int j = 0; j <= i; j++) {
                        if(j - 1 >= 0) dp[i][j] = dp[i - 1][j - 1];
                    }
                } else if(i < I){
                    if(arr[i] <= V) {
                        for(int j = 0; j <= i; j++) {
                            dp[i][j] = dp[i - 1][j];
                            if(j - 1 >= 0) dp[i][j] += dp[i - 1][j - 1];
                            dp[i][j] %= M;
                        }
                    } else {
                        for(int j = 0; j <= i; j++) {
                            dp[i][j] = 2 * dp[i - 1][j] % M;
                        }
                    }
                } else {
                    if(arr[i] < V) {
                        for(int j = 0; j <= i; j++) {
                            dp[i][j] = dp[i - 1][j];
                            if(j - 1 > 0) dp[i][j] += dp[i - 1][j - 1];
                            dp[i][j] %= M;
                        }
                    } else {
                        for(int j = 0; j <= i; j++) {
                            dp[i][j] = 2 * dp[i - 1][j] % M;
                        }
                    }
                }
            }
            for(int i = 1; i <= n; i++) {
                ans += V * dp[n][i] % M;
                ans %= M;
            }
        }
        cout << ans << endl;
    }
    
  • 相关阅读:
    Single Number II
    Pascal's Triangle
    Remove Duplicates from Sorted Array
    Populating Next Right Pointers in Each Node
    Minimum Depth of Binary Tree
    Unique Paths
    Sort Colors
    Swap Nodes in Pairs
    Merge Two Sorted Lists
    Climbing Stairs
  • 原文地址:https://www.cnblogs.com/limil/p/15022681.html
Copyright © 2011-2022 走看看