CodeCraft-20(Div. 2 abcd

时间:2020-03-12
本文章向大家介绍CodeCraft-20(Div. 2 abcd,主要包括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) << "\n";
    }
    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 << "\n" << res << "\n";
    }
    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] == '\0') 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] != '\0') 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 << "\n";
    //a1 = 0;
     //cout << a1 << "  !a1 = " << !a1 << "  ~a1 = " << ~a1 << "\n";

    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] != '\0');
            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\n"; 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 << "\n";} cout << "ennnnn\n";
    
    _rep(i,1,n) _rep(j,1,n) 
        if(d[i][j] == '\0') {cout << "INVALID\n"; return;}
    cout << "VALID\n";
    _rep(i,1,n) { _rep(j,1,n) cout << d[i][j]; cout << "\n";}
    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] << "\n";
    return;
}
int main(){
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    //taskA();
    //taskB1();
    //taskC();
    //taskD();
    taskE();
    return 0;
}

原文地址:https://www.cnblogs.com/163467wyj/p/12452043.html