第十二届蓝桥杯 2021年省赛真题 (C/C++ 大学A组) 第一场_路径 蓝桥杯 2021-程序员宅基地

技术标签: 蓝桥杯  c/c++  


解析移步对应 Java组 的题解


#A 卡片

本题总分: 5 5 5


问题描述

  小蓝有很多数字卡片,每张卡片上都是数字 0 0 0 9 9 9
  小蓝准备用这些卡片来拼一些数,他想从 1 1 1 开始拼出正整数,每拼一个,就保存起来,卡片就不能用来拼其它数了。
  小蓝想知道自己能从 1 1 1 拼到多少。
  例如,当小蓝有 30 30 30 张卡片,其中 0 0 0 9 9 9 3 3 3 张,则小蓝可以拼出 1 1 1 10 10 10,但是拼 11 11 11 时卡片 1 1 1 已经只有一张了,不够拼出 11 11 11
  现在小蓝手里有 0 0 0 9 9 9 的卡片各 2021 2021 2021 张,共 20210 20210 20210 张,请问小蓝可以从 1 1 1 拼到多少?
  提示:建议使用计算机编程解决问题。


答案提交

  这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。


3181


calcCode:

#include <stdio.h>

int n, ans, cnt;

int main() {
    
    while (1) {
    
       n = ans;
       while (n) {
    
           if (n % 10 == 1) cnt++;
           n /= 10;
       }
       if (cnt < 2021) ans++;
       else break;
    }
    printf("%d", ans);
}

#B 直线

本题总分: 5 5 5


问题描述

  在平面直角坐标系中,两点可以确定一条直线。如果有多点在一条直线上,那么这些点中任意两点确定的直线是同一条。
  给定平面上 2 × 3 2 × 3 2×3 个整点 { ( x , y ) ∣ 0 ≤ x < 2 , 0 ≤ y < 3 , x ∈ Z , y ∈ Z } \{(x, y)|0 ≤ x < 2, 0 ≤ y < 3, x ∈ Z, y ∈ Z\} { (x,y)0x<2,0y<3,xZ,yZ},即横坐标是 0 0 0 1 1 1 (包含 0 0 0 1 1 1) 之间的整数、纵坐标是 0 0 0 2 2 2 (包含 0 0 0 2 2 2) 之间的整数的点。这些点一共确定了 11 11 11 条不同的直线。
  给定平面上 20 × 21 20 × 21 20×21 个整点 { ( x , y ) ∣ 0 ≤ x < 20 , 0 ≤ y < 21 , x ∈ Z , y ∈ Z } \{(x, y)|0 ≤ x < 20, 0 ≤ y < 21, x ∈ Z, y ∈ Z\} { (x,y)0x<20,0y<21,xZ,yZ},即横坐标是 0 0 0 19 19 19 (包含 0 0 0 19 19 19) 之间的整数、纵坐标是 0 0 0 20 20 20 (包含 0 0 0 20 20 20) 之间的整数的点。请问这些点一共确定了多少条不同的直线。


答案提交

  这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。


40257


calcCode:

#include <stdio.h>

const int X = 20, Y = 21;

int linked[X][Y][X][Y], ans;

int main() {
    
    for (int x1 = 0; x1 < X; x1++)
        for (int y1 = 0; y1 < Y; ++y1) {
    
            linked[x1][y1][x1][y1] = 1;
            for (int x2 = 0; x2 < X; ++x2)
                for (int y2 = 0; y2 < Y; ++y2)
                    if (!linked[x1][y1][x2][y2]) {
    
                        int x = x1, x_offset = x1 - x2;
                        int y = y1, y_offset = y1 - y2;
                        while (x >= 0 && x < X && y >= 0 && y < Y) x -= x_offset, y -= y_offset;
                        for (x += x_offset, y += y_offset; x >= 0 && x < X && y >= 0 && y < Y; x += x_offset, y += y_offset)
                            for (int xx = x, yy = y; xx >= 0 && xx < X && yy >= 0 && yy < Y; xx += x_offset, yy += y_offset)
                                linked[x][y][xx][yy] = linked[xx][yy][x][y] = 1;
                        ans++;
                    }
        }
    printf("%d", ans);
}

#C 货物摆放

本题总分: 10 10 10


问题描述

  小蓝有一个超大的仓库,可以摆放很多货物。
  现在,小蓝有 n n n 箱货物要摆放在仓库,每箱货物都是规则的正方体。小蓝规定了长、宽、高三个互相垂直的方向,每箱货物的边都必须严格平行于长、宽、高。
  小蓝希望所有的货物最终摆成一个大的立方体。即在长、宽、高的方向上分别堆 L 、 W 、 H L、W、H LWH 的货物,满足 n = L × W × H n = L × W × H n=L×W×H
  给定 n n n,请问有多少种堆放货物的方案满足要求。
  例如,当 n = 4 n = 4 n=4 时,有以下 6 6 6 种方案: 1 × 1 × 4 1×1×4 1×1×4 1 × 2 × 2 1×2×2 1×2×2 1 × 4 × 1 1×4×1 1×4×1 2 × 1 × 2 2×1×2 2×1×2 2 × 2 × 1 2 × 2 × 1 2×2×1 4 × 1 × 1 4 × 1 × 1 4×1×1
  请问,当 n = 2021041820210418 n = 2021041820210418 n=2021041820210418 (注意有 16 16 16 位数字)时,总共有多少种方案?
  提示:建议使用计算机编程解决问题。


答案提交

  这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。


2430


calcCode:

#include <bits/stdc++.h>

typedef long long ll;

using namespace std;

ll N = 2021041820210418, n = 1, ans;

int main() {
    
    priority_queue<int> exps;
    for (int i = 2; i <= sqrt(N); i++)
        if (N % i == 0) {
    
            int exp = 0;
            while (N % i == 0)
                N /= i, exp++;
            exps.push(exp);
        }
    if (N != 1) exps.push(1);
    for (int i = 2; exps.size(); i++) {
    
        bool flag = 1;
        for (int a = 2; a < i; ++a)
            if (i % a == 0) flag = 0;
        if (flag) n *= pow(i, exps.top()), exps.pop();
    }
    for (ll i = 1; i <= n; i++)
        for (ll j = 1; j <= n; j++)
            if (n % (i * j) == 0) ans++;
    cout << ans << endl;
}

#D 路径

本题总分: 10 10 10


问题描述

  小蓝学习了最短路径之后特别高兴,他定义了一个特别的图,希望找到图中的最短路径。
  小蓝的图由 2021 2021 2021 个结点组成,依次编号 1 1 1 2021 2021 2021。对于两个不同的结点 a , b a, b a,b,如果 a a a b b b 的差的绝对值大于 21 21 21,则两个结点之间没有边相连;如果 a a a b b b 的差的绝对值小于等于 21 21 21,则两个点之间有一条长度为 a a a b b b 的最小公倍数的无向边相连。
  例如:结点 1 1 1 和结点 23 23 23 之间没有边相连;结点 3 3 3 和结点 24 24 24 之间有一条无向边,长度为 24 24 24;结点 15 15 15 和结点 25 25 25 之间有一条无向边,长度为 75 75 75
  请计算,结点 1 1 1 和结点 2021 2021 2021 之间的最短路径长度是多少。
  提示:建议使用计算机编程解决问题。


答案提交

  这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。


10266837


calcCode:

#include <stdio.h>
#include <string.h>

const int N = 2021;
int map[N + 1][N + 1];

int gcd(int a, int b) {
     return b ? gcd(b, a % b) : a; }

int lcm(int a, int b) {
     return a * b / gcd(a, b); }

int min(int a, int b) {
     return a < b ? a : b; }

int main() {
    
    memset(&map, 0x3F, sizeof map);
    for (int u = 1; u <= N; u++)
        for (int v = min(N, u + 21); v > u; --v)
            map[u][v] = map[v][u] = lcm(u, v);
    for (int k = 1; k <= N; k++)
        for (int i = 1; i <= N; i++)
            for (int j = 1; j <= N; j++)
                map[i][j] = min(map[i][j], map[i][k] + map[k][j]);
    printf("%d", map[1][N]);
}

#E 回路计数

本题总分: 15 15 15


问题描述

  蓝桥学院由 21 21 21 栋教学楼组成,教学楼编号 1 1 1 21 21 21。对于两栋教学楼 a a a b b b,当 a a a b b b 互质时, a a a b b b 之间有一条走廊直接相连,两个方向皆可通行,否则没有直接连接的走廊。
  小蓝现在在第一栋教学楼,他想要访问每栋教学楼正好一次,最终回到第一栋教学楼(即走一条哈密尔顿回路),请问他有多少种不同的访问方案?两个访问方案不同是指存在某个 i i i,小蓝在两个访问方法中访问完教学楼 i i i 后访问了不同的教学楼。
  提示:建议使用计算机编程解决问题。


答案提交

  这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。


881012367360


calcCode:

#include <bits/stdc++.h>

typedef long long ll;

using namespace std;

const int N = 21;

ll cnt[N - 1][1 << N - 1];

vector<int> graph[N];

ll dfs(int start, int status) {
    
    if (status == 0) return 1;
    if (cnt[start][status] >= 0) return cnt[start][status];
    ll sum = 0;
    for (int v : graph[start])
        if (status & (1 << v))
            sum += dfs(v, status - (1 << v));
    return cnt[start][status] = sum;
}

int gcd(int a, int b) {
     return b? gcd(b, a % b) : a; }

int main() {
    
    for (int i = 2; i <= N; i++)
        for (int j = 2; j < i; j++)
            if (gcd(i, j) == 1)
                graph[i - 2].push_back(j - 2),
                graph[j - 2].push_back(i - 2);
    memset(cnt, 0xC3, sizeof cnt);
    ll sum = 0;
    for (int i = 0; i < N - 1; i++)
        sum += dfs(i, (1 << N - 1) - (1 << i) - 1);
    cout << sum << endl;
}

#F 砝码称重

时间限制: 1.0 s 1.0\mathrm s 1.0s 内存限制: 256.0 M B 256.0\mathrm{MB} 256.0MB 本题总分: 15 15 15


问题描述

  你有一架天平和 N N N 个砝码,这 N N N 个砝码重量依次是 W 1 , W 2 , ⋅ ⋅ ⋅ , W N W_1, W_2, · · · , W_N W1,W2,,WN
  请你计算一共可以称出多少种不同的重量?
  注意砝码可以放在天平两边。


输入格式

  输入的第一行包含一个整数 N N N
  第二行包含 N N N 个整数: W 1 , W 2 , W 3 , ⋯   , W N W_1, W_2, W_3, \cdots , W_N W1,W2,W3,,WN


输出格式

  输出一个整数代表答案。


测试样例1

Input:
3
1 4 6

Output:
10

Explanation:
能称出的 10 种重量是:1、2、3、4、5、6、7、9、10、11。
1 = 1;
2 = 6 − 4 (天平一边放 6,另一边放 4);
3 = 4 − 1;
4 = 4;
5 = 6 − 1;
6 = 6;
7 = 1 + 6;
9 = 4 + 6 − 1;
10 = 4 + 6;
11 = 1 + 4 + 6。

评测用例规模与约定

  对于 50 50 50% 的评测用例, 1 ≤ N ≤ 15 1 ≤ N ≤ 15 1N15
  对于所有评测用例, 1 ≤ N ≤ 100 1 ≤ N ≤ 100 1N100 N N N 个砝码总重不超过 100000 100000 100000


背包 DP


  终于逮到一个 J a v a \mathrm{Java} Java 组没有的题,可惜是 F \mathrm F F 题,还是个简单背包。

  不过依题意若干砝码做加减运算,得到的绝对值可以视为一个可以称出的重量,

  如果我们将若干砝码可能加减出的结果放在数轴上,显然可以发现,它是以原点对称的,于是我们可以只对正整数部分做背包,然后将上一轮背包 ( 1 , w i ) (1,w_i) (1,wi) 部分的结果视为 ( − w i , − 1 ) (-w_i, -1) (wi,1),可以减少算法的常数。

#include <bits/stdc++.h>

using namespace std;

const int N = 100000;

bool dp[N + 1 << 1] = {
    1}, bf[N + 1 << 1] = {
    1};

int n, w, ans;

int main() {
    
    cin >> n;
    while (n--) {
    
        cin >> w;
        swap(dp, bf);
        for (int i = N; i >= w; i--) dp[i] = bf[i] | bf[i - w] | bf[i + w];
        for (int i = 1; i < w; i++) dp[i] |= bf[w - i];
    }
    for (int i = 1; i <= N; i++) if (dp[i]) ans++;
    cout << ans << endl;
}

#G 异或数列

时间限制: 1.0 s 1.0\mathrm s 1.0s 内存限制: 256.0 M B 256.0\mathrm{MB} 256.0MB 本题总分: 20 20 20


   A l i c e \mathrm{Alice} Alice B o b \mathrm{Bob} Bob 正在玩一个异或数列的游戏。初始时, A l i c e \mathrm{Alice} Alice B o b \mathrm{Bob} Bob 分别有一个整数 a a a b b b,有一个给定的长度为 n n n 的公共数列 X 1 , X 2 , ⋯   , X n X_1, X_2, \cdots , X_n X1,X2,,Xn
   A l i c e \mathrm{Alice} Alice B o b \mathrm{Bob} Bob 轮流操作, A l i c e \mathrm{Alice} Alice 先手,每步可以在以下两种选项中选一种:
  选项 1 1 1:从数列中选一个 X i X_i Xi A l i c e \mathrm{Alice} Alice 的数异或上,或者说令 a a a 变为 a ⊕ X i a ⊕ X_i aXi。(其中 ⊕ ⊕ 表示按位异或)
  选项 2 2 2:从数列中选一个 X i X_i Xi B o b \mathrm{Bob} Bob 的数异或上,或者说令 b b b 变为 b ⊕ X i b ⊕ X_i bXi
  每个数 X i X_i Xi 都只能用一次,当所有 X i X_i Xi 均被使用后( n n n 轮后)游戏结束。游戏结束时,拥有的数比较大的一方获胜,如果双方数值相同,即为平手。
  现在双方都足够聪明,都采用最优策略,请问谁能获胜?


输入格式

  每个评测用例包含多组询问。询问之间彼此独立。
  输入的第一行包含一个整数 T T T,表示询问数。
  接下来 T T T 行每行包含一组询问。其中第 i i i 行的第一个整数 n i n_i ni 表示数列长度,随后 n i n_i ni 个整数 X 1 , X 2 , ⋯   , X n i X_1, X_2, \cdots , X_{ni} X1,X2,,Xni 表示数列中的每个数。


输出格式

  输出 T T T 行,依次对应每组询问的答案。
  每行包含一个整数 1 1 1 0 0 0 − 1 −1 1 分别表示 A l i c e \mathrm{Alice} Alice 胜、平局或败。


测试样例1

Input:
4
1 1
1 0
2 2 1
7 992438 1006399 781139 985280 4729 872779 563580

Output:
1
0
1
1

评测用例规模与约定

  对于所有评测用例, 1 ≤ T ≤ 200000 1 \leq T \leq 200000 1T200000 1 ≤ ∑ i = 1 T n i ≤ 200000 1 \leq \sum_{i=1}^T n_i \leq 200000 1i=1Tni200000 0 ≤ X i < 2 20 0 \leq X_i < 2^{20} 0Xi<220


#include <stdio.h>
#include <math.h>

int T, S, n, A[200010];

int main() {
    
    scanf("%d", &T);
    while (T--) {
    
        S = 0;
        scanf("%d", &n);
        for (int i = 0; i < n; ++i)
        	scanf("%d", &A[i]), S ^= A[i];
        if (S) {
    
            int k = log2(S), a = 0;
            for (int i = 0; i < n; ++i) if (A[i] >> k & 1) ++a;
            if (n & 1 || a == 1) printf("1\n");
            else printf("-1\n");
        } else printf("0\n");
    }
}

#H 左孩子右兄弟

时间限制: 1.0 s 1.0\mathrm s 1.0s 内存限制: 256.0 M B 256.0\mathrm{MB} 256.0MB 本题总分: 20 20 20


问题描述

  对于一棵多叉树,我们可以通过 “左孩子右兄弟” 表示法,将其转化成一棵二叉树。
  如果我们认为每个结点的子结点是无序的,那么得到的二叉树可能不唯一。换句话说,每个结点可以选任意子结点作为左孩子,并按任意顺序连接右兄弟。
  给定一棵包含 N N N 个结点的多叉树,结点从 1 1 1 N N N 编号,其中 1 1 1 号结点是根,每个结点的父结点的编号比自己的编号小。请你计算其通过 “左孩子右兄弟” 表示法转化成的二叉树,高度最高是多少。注:只有根结点这一个结点的树高度为 0 0 0
  例如如下的多叉树:
请添加图片描述
  可能有以下 3 3 3 种 (这里只列出 3 3 3 种,并不是全部) 不同的 “左孩子右兄弟”表示:
请添加图片描述
  其中最后一种高度最高,为 4 4 4


输入格式

  输入的第一行包含一个整数 N N N
  以下 N − 1 N −1 N1 行,每行包含一个整数,依次表示 2 2 2 N N N 号结点的父结点编号。


输出格式

  输出一个整数表示答案。


测试样例1

Input:
5
1
1
1
2

Output:
4

评测用例规模与约定

  对于 30 30 30% 的评测用例, 1 ≤ N ≤ 20 1 ≤ N ≤ 20 1N20
  对于所有评测用例, 1 ≤ N ≤ 100000 1 ≤ N ≤ 100000 1N100000


#include <bits/stdc++.h>

using namespace std;

#define N 100005

vector<int> tree[N];

int dp(int root) {
    
    if (!tree[root].size()) return 0;
    int res = 0;
    for (int son : tree[root])
        res = max(res, dp(son));
    return res + tree[root].size();
}

int main() {
    
    int n, t;
    cin >> n;
    for (int i = 2; i <= n; ++i)
        cin >> t, tree[t].push_back(i);
    cout << dp(1) << endl;
}

#I 括号序列

时间限制: 1.0 s 1.0\mathrm s 1.0s 内存限制: 256.0 M B 256.0\mathrm{MB} 256.0MB 本题总分: 25 25 25


问题描述

  给定一个括号序列,要求尽可能少地添加若干括号使得括号序列变得合法,当添加完成后,会产生不同的添加结果,请问有多少种本质不同的添加结果。
  两个结果是本质不同的是指存在某个位置一个结果是左括号,而另一个是右括号。
  例如,对于括号序列 (((),只需要添加两个括号就能让其合法,有以下几种不同的添加结果:()()()、()(())、(())()、(()()) 和 ((()))。


输入格式

  输入一行包含一个字符串 s s s,表示给定的括号序列,序列中只有左括号和右括号。


输出格式

  输出一个整数表示答案,答案可能很大,请输出答案除以 1000000007 1000000007 1000000007 (即 1 0 9 + 7 10^{9} + 7 109+7) 的余数。


测试样例1

Input:
((()

Output:
5

评测用例规模与约定

  对于 40 40 40% 的评测用例, ∣ s ∣ ≤ 200 |s| ≤ 200 s200
  对于所有评测用例, 1 ≤ ∣ s ∣ ≤ 5000 1 ≤ |s| ≤ 5000 1s5000


#include <stdio.h>
#include <string.h>

typedef long long ll;

#define N 5555

int dp[N][N], p = 1000000007;

char str[N] = {
    '$'};

int calc(char *str) {
    
    memset(dp, 0, sizeof dp);
    dp[0][0] = 1;
    int opening = 0, n = strlen(str) - 1;
    for (int i = 1; i <= n; i++) {
    
        if (str[i] == '(') {
    
            for (int j = 1; j <= n; j++)
                dp[i][j] = dp[i - 1][j - 1];
            opening++;
        }
        else {
    
            dp[i][0] = (dp[i - 1][0] + dp[i - 1][1]) % p;
            for (int j = 1; j <= n; j++)
                dp[i][j] = (dp[i][j - 1] + dp[i - 1][j + 1]) % p;
            if (opening) opening--;
        }
    }
    return dp[n][opening];
}

int reverse(char *str) {
    
    for (int i = 1, j = strlen(str) - 1; i <= j; i++, j--) {
    
        char temp = str[i] ^ 1;
        str[i] = str[j] ^ 1;
        str[j] = temp;
    }
}

int main() {
    
    scanf("%s", str + 1);
    ll ans = calc(str);
    reverse(str);
    printf("%d\n", ans * calc(str) % p);
}

#J 分果果

时间限制: 1.0 s 1.0\mathrm s 1.0s 内存限制: 256.0 M B 256.0\mathrm{MB} 256.0MB 本题总分: 25 25 25


问题描述

  小蓝要在自己的生日宴会上将 n n n 包糖果分给 m m m 个小朋友。每包糖果都要分出去,每个小朋友至少要分一包,也可以分多包。
  小蓝已经提前将糖果准备好了,为了在宴会当天能把糖果分得更平均一些,小蓝要先计算好分配方案。
  小蓝将糖果从 1 1 1 n n n 编号,第 i i i 包糖果重 w i w_i wi。小朋友从 1 1 1 m m m 编号。每个小朋友只能分到编号连续的糖果。小蓝想了很久没想出合适的分配方案使得每个小朋友分到的糖果差不多重。因此需要你帮他一起想办法。为了更好的分配糖果,他可以再买一些糖果,让某一些编号的糖果有两份。当某个编号的糖果有两份时,一个小朋友最多只能分其中的一份。
  请找一个方案,使得小朋友分到的糖果的最大重量和最小重量的差最小,请输出这个差。
  例如,小蓝现在有 5 5 5 包糖果,重量分别为 6 , 1 , 2 , 7 , 9 6, 1, 2, 7, 9 6,1,2,7,9,如果小蓝要分给两个小朋友,则他可以将所有糖果再买一份,两个小朋友都分到 1 1 1 5 5 5 包糖果,重量都是 25 25 25,差为 0 0 0
  再如,小蓝现在有 5 5 5 包糖果,重量分别为 6 , 1 , 2 , 7 , 9 6, 1, 2, 7, 9 6,1,2,7,9,如果小蓝要分给三个小朋友,则他可以将第 3 3 3 包糖果再买一份,第一个小朋友分 1 1 1 3 3 3 包,第二个小朋友分 3 3 3 4 4 4 包,第三个小朋友分第 5 5 5 包,每个小朋友分到的重量都是 9 9 9,差为 0 0 0
  再如,小蓝现在有 5 5 5 包糖果,重量分别为 6 , 1 , 2 , 7 , 9 6, 1, 2, 7, 9 6,1,2,7,9,如果小蓝要分给四个小朋友,则他可以将第 3 3 3 包和第 5 5 5 包糖果再买一份,仍然可以每个小朋友分到的重量都是 9 9 9,差为 0 0 0
  再如,小蓝现在有 5 5 5 包糖果,重量分别为 6 , 1 , 2 , 7 , 9 6, 1, 2, 7, 9 6,1,2,7,9,如果小蓝要分给五个小朋友,则他可以将第 4 4 4 包和第 5 5 5 包糖果再买一份,第一个小朋友分第 1 1 1 2 2 2 包重量为 7 7 7,第二个小朋友分第 3 3 3 4 4 4 包重量为 9 9 9,第三个小朋友分第 4 4 4 包重量为 7 7 7,第四个和第五个小朋友都分第 5 5 5 包重量为 9 9 9。差为 2 2 2


输入格式

  输入第一行包含两个整数 n n n m m m,分别表示糖果包数和小朋友数量。
  第二行包含 n n n 个整数 w 1 , w 2 , ⋅ ⋅ ⋅ , w n w_1, w_2, · · · , w_n w1,w2,,wn,表示每包糖果的重量。


输出格式

  输出一个整数,表示在最优情况下小朋友分到的糖果的最大重量和最小重量的差。


测试样例1

Input:
5 2
6 1 2 7 9

Output:
0

测试样例2

Input:
5 5
6 1 2 7 9

Output:
2

评测用例规模与约定

  对于 30 30 30% 的评测用例, 1 ≤ n ≤ 10 1 \leq n \leq 10 1n10 1 ≤ m ≤ 10 1 \leq m \leq 10 1m10 1 ≤ w i ≤ 10 1 \leq w_i \leq 10 1wi10
  对于 60 60 60% 的评测用例, 1 ≤ n ≤ 30 1 \leq n \leq 30 1n30 1 ≤ m ≤ 20 1 \leq m \leq 20 1m20 1 ≤ w i ≤ 30 1 \leq w_i \leq 30 1wi30
  对于所有评测用例, 1 ≤ n ≤ 100 1 \leq n \leq 100 1n100 1 ≤ m ≤ 50 1 \leq m \leq 50 1m50 1 ≤ w i ≤ 100 1 \leq w_i \leq 100 1wi100。在评测数据中, w i w_i wi 随机生成,在某个区间均匀分布。


#include <stdio.h>
#include <string.h>

int dp[51][101][101], W[101], n, m, ans = 0x3F3F3F3F;

int max(int arg1, int arg2) {
     return arg1 > arg2 ? arg1 : arg2; }

int min(int arg1, int arg2) {
     return arg1 < arg2 ? arg1 : arg2; }

int main() {
    
    memset(dp, 0x3F, sizeof dp);
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; i++)
        scanf("%d", &W[i]), W[i] += W[i - 1];
    dp[0][0][0] = 0;
    for (int minW = W[n] * 2 / m; minW > 0; minW--) {
    
        for (int i = 1; i <= m; i++)
            for (int j = 1; j <= n; j++) {
    
                int trans2 = 0, trans3 = 0;
                for (int k = 1; k <= j; k++) {
    
                    dp[i][j][k] = dp[i][j][k - 1];
                    while (trans2 < k && W[j] - W[trans2 + 1] >= minW &&
                    	max(dp[i - 1][trans2 + 1][trans2 + 1], W[j] - W[trans2 + 1]) <= max(dp[i - 1][trans2][trans2], W[j] - W[trans2])) trans2++;
                    if (W[j] - W[trans2] >= minW)
                        dp[i][j][k] = min(dp[i][j][k], max(dp[i - 1][trans2][trans2], W[j] - W[trans2]));
                    while (trans3 < k && W[j] - W[trans3 + 1] >= minW &&
                        max(dp[i - 1][k][trans3 + 1], W[j] - W[trans3 + 1]) <= max(dp[i - 1][k][trans3 + 1], W[j] - W[trans3])) trans3++;
                    if (W[j] - W[trans3] >= minW)
                        dp[i][j][k] = min(dp[i][j][k], max(dp[i - 1][k][trans3], W[j] - W[trans3]));
                }
            }
        ans = min(ans, dp[m][n][n] - minW);
    }
    printf("%d\n", ans);
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_43449564/article/details/123446194

智能推荐

Springboot和Vue+MYSQL项目(基本介绍+前后端结合初步项目)+maven+mybatis_完整的vue +springboot mybatis maven项目-程序员宅基地

文章浏览阅读1.4k次,点赞9次,收藏8次。Springboot和Vue+MYSQL项目(基本介绍+前后端结合初步项目)+maven+mybatis_完整的vue +springboot mybatis maven项目

vue3项目 目录结构没有config文件夹_vue项目没有config/index.js-程序员宅基地

文章浏览阅读5.6k次,点赞9次,收藏13次。问题:在页面完成后,打包上线页面出现白屏问题。百度到的,解决办法是,改变config文件夹下,index.js中,build下的 assetsPublicPath:"/" => assetsPublicPath:"./"。随后发现创建的是vue3的项目没有config文件夹。解决:在项目根目录,创建 vue.config.js 文件,文件内容如下:module.exports={ publicPath:"./"}解决!..._vue项目没有config/index.js

简述CPU的大小端 (易于理解)_cpu大小端-程序员宅基地

文章浏览阅读2.7k次,点赞2次,收藏9次。CPU大小端模式一、为何会有大小端之分?在计算机系统中,一个存储单元的大小为一个字节(1Byte = 8bit),一个存储单元对应一个地址单元。(按字节编址)对于位数大于8位的处理器,如16,32,64位等,由于其寄存器宽度大于一个字节,必然存在着多字节顺序安排的问题。这就衍生出了大端存储、小端存储的差异。二、什么是大端和小端?大端存储:在 一个数据要占用的内存空间 中,高位字节存储在低地址,低位字节存储在高地址。(与人们的阅读顺序相符)小端存储:在 一个数据要占用的内存空间 中_cpu大小端

uni-app:微信小程序分享页面到微信好友和朋友圈_uniapp小程序分享到朋友圈,打开接口加载失败-程序员宅基地

文章浏览阅读7.5k次。添加生命周期函数就生效,可以自定义onLoad(){},/* * uniapp微信小程序分享页面到微信好友*/onShareAppMessage() {},/* * uniapp微信小程序分享页面到微信朋友圈*/onShareTimeline() {},参考uni-app学习:uniapp微信小程序分享页面到微信好友和朋友圈。..._uniapp小程序分享到朋友圈,打开接口加载失败

SQL Server实验四 数据的简单查询 全注释版_1.在订单数据库orderdb中,完成如下的查询: (1)查询所有业务部门的员工姓名,职称,-程序员宅基地

文章浏览阅读4.2k次,点赞9次,收藏44次。select employeename,headship,salary from Employee/查询所有员工的姓名,职务,薪水/select customername,Address from customer where CustomerName like’%有限%’/查询名字中含有限的客户名和地址/select * from Employee where EmployeeName like’王%成’/查询姓王且名字最后一个字为成的员工/select employeename,depart_1.在订单数据库orderdb中,完成如下的查询: (1)查询所有业务部门的员工姓名,职称,

Docker部署LNMP环境_docker lnmp 怎么访问-程序员宅基地

文章浏览阅读1.1k次,点赞4次,收藏7次。Docker部署LNMP环境172.16.10.0/24Nginx:172.16.10.10Mysql:172.16.10.20PHP:172.16.10.30网站的访问主目录:/wwwrootNginx的配置文件:/docker[root@localhost ~]# docker run -itd --name test nginx:latest[..._docker lnmp 怎么访问

随便推点

PowerSI提取S参数(插损、回损、串扰分析)_power si-程序员宅基地

文章浏览阅读9.3k次,点赞3次,收藏65次。PowerSI提取S参数(插损、回损、串扰分析)0、PowerSI仿真前设置:首先在应用PowerSI进行这些仿真之前,需要对PowerSI进行如下设置。1、PowerSI提取S参数S参数反应无源通道的所有信息,通过S参数可以得到回损、插损、串扰、模态转换等所有的无源信息。Sigrity中使用Model Extraction(2.5D求解器,适用范围5G以下)进行S参数的提取。PowerSI仿真步骤如下:① 检查叠层检查叠层是否正确,材料参数是否正确,以及设置设置过孔的孔铜厚度,过_power si

全志F1C200S F1C100S 介绍-程序员宅基地

文章浏览阅读7.4w次,点赞75次,收藏249次。很久以前发现了一颗性价比极高而且比较好玩的SOC,那就是全志F1C100S F1C200S,其中F1C100S内置32MB DDR1内存,F1C200S内置64MB DDR1内存。而他们能从淘宝轻松的买到,如果找靠谱的店家或者找代理商的话,F1C100S 是10块钱一片,F1C200S是13块钱一片。从淘宝买一定要注意分辨是拆机还是库存还是正规代理货源,千万别图便宜,拆机良率可能20%..._f1c100s

go语言错题集(坑)【三】_type *shopi.shopclient is pointer to interface, no-程序员宅基地

文章浏览阅读449次。系列相关:go语言错题集(坑)【一】go语言错题集(坑)【二】go语言错题集(坑)【三】目录不要对Go并发函数的执行时机做任何假设假设T类型的方法上接收器既有T类型的,又有*T指针类型的,那么就不可以在不能寻址的T值上调用*T接收器的方法一个包含nil指针的接口不是nil接口将map转化为json字符串的时候,json字符串中的顺序和map赋值顺序无关Js..._type *shopi.shopclient is pointer to interface, not interface

HashMap原理-1.8-程序员宅基地

文章浏览阅读65次。HashMap原理-1.8 之前总结过HashMap的原理,同时对源码进行了阅读,不过是针对JDK1.7的版本,同样针对1.8的版本也来做一遍记录1.HashMap1.8针对1.7的修改点有哪些?JJDK1.8对HashMap底层的实现进行了优化,例如引入红...

QTableView/QTableWidget 实现hover一行效果_tablewidget 只有部分单元格有hover-程序员宅基地

文章浏览阅读4.6k次,点赞5次,收藏45次。QTableView/QTableWidget 实现hover一行效果在网上看到一些实现这个效果都是通过鼠标事件判断悬浮在哪一行实现的,这里提供另一种思路。在Qt的模型/视图/代理框架里面,关于item的绘制是交给代理实现的,默认的QStyledItemDelegate的paint会去调用virtual void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const;这个虚函数,初始化一些_tablewidget 只有部分单元格有hover

使用python 驱动 lotus notes发送邮件_python setcontentfromtext-程序员宅基地

文章浏览阅读6.2k次。python lotus notes mail_python setcontentfromtext