zoukankan      html  css  js  c++  java
  • CF339

    C. Xenia and Weights

    有1...10k的砝码,在天枰上,左右轮流放置砝码,要求之后左右轮流比另一侧重量要大,要求相邻两次砝码不能相同。

    解题报告给出(i,j,k)表示balance,j表示最后一次的砝码重量,k表示第几步,然后表示从点(0,0,0)->(x,y,m)的图论问题,跟动态规划是等价的,复杂度是O(w^3*m)。

    我给出了一个比上述算法更优的一个算法,做法是用dp[i][j]表示第i步balance达到j时的所有可能的砝码情况的二进制mask,复杂度是O(w^2*m),但要求w<32。

    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    int dp[1005][25];
    char w[15];
    
    int main() {
        int m;
        scanf("%s%d", w, &m);
    
        memset(dp, 0, sizeof(dp));
        dp[0][10] = 1;
    
        for (int i = 1; i <= m; i++) {
            for (int j = 0; j <= 20; j++) {
                if (dp[i - 1][j] > 0) {
                    for (int k = 1; k <= 10; k++) if (w[k - 1] == '1') {
                        if (dp[i - 1][j] ^ (1 << k)) {
                            if (j >= 10 && j - k < 10) {
                                dp[i][j - k] |= (1 << k);
                            } else if (j < 10 && j + k > 10) {
                                dp[i][j + k] |= (1 << k);
                            } 
                        }
                    }
                }
            } 
        }
    
        int ans_j = -1;
        for (int j = 0; j <= 20; j++) if (dp[m][j] > 0)
            ans_j = j;
    
        if (ans_j == -1) {
            printf("NO
    ");
        } else {
            printf("YES
    "); 
            int i = m;
            vector<int> ans;
            int last = 0;
            while (i > 0) {
                for (int j = 1; j <= 10; j++) {
                    if (dp[i][ans_j] & (1 << j)) {
                        if (j == last) continue;
    
                        ans.push_back(j);
                        
                        if (ans_j >= 10) ans_j -= j;
                        else ans_j += j;
    
                        last = j;
    
                        break;
                    }
                }
                i--;
            }
            for (i = ans.size() - 1; i >= 0; i--) {
                printf("%d ", ans[i]);
            }
            printf("
    ");
        }
    }

    D. Xenia and Bit Operations

    很裸的一个线段树了。

    #include <cstdio>
    #include <iostream>
    using namespace std;
    
    const int MAXN = 1 << 17;
    
    int num[MAXN];
    
    class SegNode {
    public:
        int L, R;
        int level, sum;
    } node[MAXN * 4];
    
    class SegTree {
    public:
        void build(int r, int L, int R) {
            node[r].L = L;
            node[r].R = R;
    
            if (L == R) {
                // leaf
                node[r].level = 0;
                node[r].sum = num[L];
            } else {
                // non leaf 
                int M = (L + R) / 2;
                build(2 * r, L, M);
                build(2 * r + 1, M + 1, R);
                node[r].level = node[2 * r].level + 1;
                if (node[r].level & 1) {
                    node[r].sum = node[2 * r].sum | node[2 * r + 1].sum;
                } else {
                    node[r].sum = node[2 * r].sum ^ node[2 * r + 1].sum;
                }
            }
        }
        void update(int r, int p, int b) {
            if (node[r].L == node[r].R) {
                node[r].sum = b; 
            } else {
                if (p <= node[2 * r].R) {
                    // left
                    update(2 * r, p, b);
                } else if (p >= node[2 * r + 1].L) {
                    // right 
                    update(2 * r + 1, p, b);
                }
                if (node[r].level & 1) {
                    node[r].sum = node[2 * r].sum | node[2 * r + 1].sum;
                } else {
                    node[r].sum = node[2 * r].sum ^ node[2 * r + 1].sum;
                }
            } 
        }
    } tree;
    
    int main() {
        int n, m;
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= (1 << n); i++) {
            scanf("%d", &num[i]);
        }
        tree.build(1, 1, 1 << n);
        for (int i = 0; i < m; i++) {
            int p, b;
            scanf("%d%d", &p, &b);
            tree.update(1, p, b);
            printf("%d
    ", node[1].sum);
        }
    }
  • 相关阅读:
    1144 The Missing Number (20分)
    1145 Hashing
    1146 Topological Order (25分)
    1147 Heaps (30分)
    1148 Werewolf
    1149 Dangerous Goods Packaging (25分)
    TypeReference
    Supervisor安装与配置()二
    谷粒商城ES调用(十九)
    Found interface org.elasticsearch.common.bytes.BytesReference, but class was expected
  • 原文地址:https://www.cnblogs.com/litstrong/p/3285099.html
Copyright © 2011-2022 走看看