• CodeCraft-20(Div. 2 abcd


     看 Editorial 补题的蒟蒻

    传送门

    A Grade Allocation standard input/output 1 s, 256 MB Submit Add to favourites x8615

      cout << min(sum(ai), m);
    B String Modification standard input/output 1 s, 256 MB Submit Add to favourites x5026

      t <= 5e3,  sum(n) <= 5e3, 所以可以直接暴力枚举 k, 写几个字符串模拟下会发现
      s: 12345 

      k = 1, s1 = 12345      k = 2, s1 = 23451     k = 3, s1 = 34521     k = 4, s1 = 45123    k = 5, s1 = 54321

       s : 123456

           k = 1, s1 = 123456    k = 2,   s1 =  234561   k = 3, s1 = 345612   k = 4, s1 = 456321  k = 5, s1 = 561234   k = 6, s1 = 654321

      可以发现   每个 k,的前缀字符串为 sk+1……sn   后缀为 s1……sk , 而且如果 k 和 n 奇偶性相同的时候 需要把后缀串翻转  
      最后将最小字典序的字符串 和 最小 k 输出即可


    C Primitive Primes standard input/output 1.5 s, 256 MB Submit Add to favourites x3223

      Hence no prime divides all the coefficients of the polynomial. We call such polynomials primitive polynomials. This question in a way tells us that the product of two primitive polynomials is also a primitive polynomial.  本原多项式 的 乘积依然为本原多项式

      给你两个多项式, 问他们的乘积多项式的系数不能 整除 p 的任意系数下标是 且保证有解, 

             因为 xi+j 的系数是      (a0∗bi+j+a1∗bi+j−1+…)+ai∗bj+(ai+1∗bj−1+ai+2∗bj−2+…)  可以得知 当 ai 和 bj  分别是不能整除 p 的第一个数时 前面括号 和 后面括号 里的值都为 p的倍数, 但ai*bj 都不是 p的倍数  故 xi+j 的系数 不能整除 p 


    D Nash Matrix standard input/output 2 s, 256 MB Submit Add to favourites x1478

      给你n*n 的格子, 每个格子拥有一个坐标 表示 他能到的另一个点坐标 (如果是-1,-1 代表这个格子在一个环中且永远不会到障碍点), (如果该坐标就为自己  则代表这是一个blocked  zone 障碍点), 所以当点为  -1,-1 时 可以找找上下左右是否有 -1,-1  然后标记成 LR  UD  这样的死循环, 后续再根据 X 的位置 再上下左右 dfs倒推下, 最后 如果 死循环无法坐成 或者 答案棋盘里还有未标记点 则 INVALID 代码如下


    E Team Building standard input/output 3 s, 256 MB Submit Add to favourites x837
      状压dp, p 不大 所以可以用 一个mask 用它的p个二进制未表示 p 个运动员位置是否被选 0 1, 且 按照a[i]  降序先排个序  这里由于 a数组 和 s 数组有关联 所以不能直接对 a数组 排序, 可以用个小技巧 定义一个新的数组 为a数组的下标  按照 a数组 降序的规则对新数组进行排序, 排序的原因是 当这个人不做运动员的时候 他作为观众贡献是最大的 因为它比后面的人做观众贡献都要更大,

    然后状态转移方程为 dp[i][mask] = max(dp[i][mask], dp[i-1][mask^(1<<j)]+s[x][j]);

    //前i-1个人里面 当第j个运动员未被选的状态 转移到当前的第j个运动员被选的状态(将第i个人作为 第j个运动员)

      dp[i][mask]  表示前i个人运动员状态为 mask的最大贡献值  最后输出dp[n][(1<<p)-1] 即可

    //CodeCraft-20 (Div. 2)
    
    #include <bits/stdc++.h> 
    using namespace std;
    #define ll long long
    #define _for(i,a,b) for(int i = (a); i < (b); i++) 
    #define _rep(i,a,b) for(int i = (a); i <= (b); i++)
    void taskA(){
        int t; cin >> t;
        while(t--) {
            int n,m; cin >> n >> m;
            vector<int> a(n);
            ll sum = 0;
            _for(i,0,n) cin >> a[i], sum+=a[i];
            cout << min(sum, (ll)m) << "
    ";
        }
        return;
    }
    void taskB1(){
        int t; cin >> t;
        while(t--) {
            int n; cin >> n; 
            string s; cin >> s;
            string ans = s;
            int res = 1;
            _rep(k,2,n) {
                string ans_pre = s.substr(k-1, n);
                string ans_suf = s.substr(0, k-1);
           
                if(n%2 == k%2) 
                    reverse(ans_suf.begin(), ans_suf.end());
        // It can be observed that the suffix will be s1..sk−1 if n and k have the same parity and sk−1..s1 otherwise.
                ans_pre += ans_suf;
                if(ans > ans_pre) ans = ans_pre, res = k;
            }
            cout << ans << "
    " << res << "
    ";
        }
        return;
    }
    void taskC(){
        int n,m,p; cin >> n >> m >> p;
        vector<ll> a(n), b(m), c(n+m-1, 0);
        _for(i,0,n) cin >> a[i], a[i] %= p;
        _for(i,0,m) cin >> b[i], b[i] %= p;
        int x = 0, y = 0;
        while(!a[x]) x++;
        while(!b[y]) y++;
        cout << x+y;
        return;
    }
    const int N = 1010;
    int x[N][N], y[N][N], n;
    char d[N][N];
    bool connnect(int x1, int y1, int x2, int y2, char c1, char c2) {
        if(x2 < 1 or x2 > n or y2 < 1 or y2 > n) return false;
        if(x[x2][y2] == -1) {
            d[x1][y1] = c1;
            if(d[x2][y2] == '') d[x2][y2] = c2;
            return true;
        } return false;
    }
    void dfs(int x1, int y1, char c1) {
        if(x1 < 1 or x1 > n or y1 < 1 or y1 > n) return;
        if(d[x1][y1] != '') return;
    
        d[x1][y1] = c1;
        if(x[x1][y1] == x[x1+1][y1] and y[x1+1][y1] == y[x1][y1])
            dfs(x1+1, y1, 'U');
        if(x[x1][y1] == x[x1-1][y1] and y[x1-1][y1] == y[x1][y1])
            dfs(x1-1, y1, 'D');
        if(x[x1][y1] == x[x1][y1-1] and y[x1][y1-1] == y[x1][y1])
            dfs(x1, y1-1, 'R');
        if(x[x1][y1] == x[x1][y1+1] and y[x1][y1+1] == y[x1][y1])
            dfs(x1, y1+1, 'L');
        return;
    }
    void taskD(){
        //int a1 = -1; cout << a1 << "  !a1 = " << !a1 << "  ~a1 = " << ~a1 << "
    ";
        //a1 = 0;
         //cout << a1 << "  !a1 = " << !a1 << "  ~a1 = " << ~a1 << "
    ";
    
        cin >> n;
        _rep(i,1,n) _rep(j,1,n)  cin >> x[i][j] >> y[i][j];
        _rep(i,1,n) _rep(j,1,n) {
            if(x[i][j] == -1) {
                bool flag = (d[i][j] != '');
                if(!flag) flag = connnect(i, j, i+1, j, 'D', 'U');
                if(!flag) flag = connnect(i, j, i-1, j, 'U', 'D');
                if(!flag) flag = connnect(i, j, i, j+1, 'R', 'L');
                if(!flag) flag = connnect(i, j, i, j-1, 'L', 'R');
                if(!flag) {cout << "INVALID
    "; return;}
            } else if(x[i][j] == i and y[i][j] == j) dfs(i, j, 'X');
        }
    
        //_rep(i,1,n) { _rep(j,1,n) cout << d[i][j]; cout << "
    ";} cout << "ennnnn
    ";
        
        _rep(i,1,n) _rep(j,1,n) 
            if(d[i][j] == '') {cout << "INVALID
    "; return;}
        cout << "VALID
    ";
        _rep(i,1,n) { _rep(j,1,n) cout << d[i][j]; cout << "
    ";}
        return;
    }
    const int N = 1e5+100;
    ll dp[N][(1<<7)+5], s[N][8], a[N], idx[N];
    bool cmp(int x, int y) {
        return a[x] > a[y];
    }
    void taskE(){
        int n, p, k; cin >> n >> p >> k;
        _rep(i,1,n)  cin >> a[i];
        _rep(i,1,n) _for(j,0,p) cin >> s[i][j];
        _rep(i,1,n) idx[i] = i;
        sort(idx+1, idx+n+1, cmp);
        memset(dp, -1, sizeof dp);
        dp[0][0] = 0;
        _rep(i,1,n) {
            int x = idx[i];
            _for(mask,0,(1<<p)) {   
                int ct = 0;
                _for(j,0,p) if(mask&(1<<j)) ct++;
                int z =  i-1-ct;
                if(z < k) {//观众席给个座位
                    if(dp[i-1][mask] != -1)
                        dp[i][mask] = dp[i-1][mask]+a[x];
                } else {//满了
                    if(dp[i-1][mask] != -1)
                        dp[i][mask] = dp[i-1][mask];
                }
                _for(j,0,p) if(mask&(1<<j) && dp[i-1][mask^(1<<j)] != -1)
                    dp[i][mask] = max(dp[i][mask], dp[i-1][mask^(1<<j)]+s[x][j]);
        //前i-1个里面 去掉没有选第j个运动员的状态 转移到当前的选了第j的状态(将第i个人作为 第j个运动员)
            }
        }
        cout << dp[n][(1<<p)-1] << "
    ";
        return;
    }
    int main(){
        ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
        //taskA();
        //taskB1();
        //taskC();
        //taskD();
        taskE();
        return 0;
    }
  • 相关阅读:
    [模板]LCA
    洛谷 P1103 书本整理(动规)
    [模板]KMP字符串匹配
    [模板]优先队列(堆)
    Java面试题10(如何取到set集合的第一个元素)
    Java集合操作类Collections的一些常用方法
    本机不装Oracle,使用plsql连接远程Oracle的方法
    ORACLE配置tnsnames.ora文件实例
    JS正则表达式验证数字
    diea破解
  • 原文地址:https://www.cnblogs.com/163467wyj/p/12452043.html
Copyright © 2020-2023  润新知