2024年CSP-J暑假冲刺训练营(4):贪心

例题

1. [THUPC 2023 初赛] 众数

题目描述

你有若干个 [ 1 , n ] [1,n] [1,n] 内的正整数:对于 1 ≤ i ≤ n 1 \le i \le n 1in,你有 a i a_i ai 个整数 i i i。设 S = ∑ i = 1 n a i S = \sum_{i=1}^n a_i S=i=1nai
对于一个序列 p 1 , p 2 , ⋯   , p l p_1,p_2,\cdots,p_l p1,p2,,pl,定义其众数 maj ( p 1 , p 2 , ⋯   , p l ) \text{maj}(p_1,p_2,\cdots,p_l) maj(p1,p2,,pl) 为出现次数最多的数。若有多个数出现次数最多,则其中最大的数为其众数。
现在你需要把这 S S S 个数排成一个序列 b 1 , b 2 , ⋯   , b S b_1,b_2,\cdots,b_S b1,b2,,bS,使得 ∑ i = 1 S maj ( b 1 , b 2 , ⋯   , b i ) \sum_{i=1}^S \text{maj}(b_1,b_2,\cdots,b_i) i=1Smaj(b1,b2,,bi) 最大。输出该最大值。

输入格式

第一行一个整数 n n n,表示值域。
接下来一行 n n n 个正整数 a 1 , a 2 , ⋯   , a n a_1,a_2,\cdots,a_n a1,a2,,an,表示每种数的个数。

输出格式

输出一行一个正整数表示 ∑ i = 1 S maj ( b 1 , b 2 , ⋯   , b i ) \sum_{i=1}^S \text{maj}(b_1,b_2,\cdots,b_i) i=1Smaj(b1,b2,,bi) 的最大值。

样例1

输入

3
1 3 2

输出

17
#include <iostream>
#include <algorithm>
using namespace std;

int n;
int ans, maxn;
int a[100005];
int f[100005];

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    
    for (int i = n; i >= 1; i--) {
        while (maxn < a[i]) {
            maxn++;
            f[maxn] = f[maxn-1]+i;
        }
        ans += f[a[i]];
    }
    
    cout << ans;
    return 0;
}

2. 寻找平面上的极大点

题目描述

在一个平面上,如果有两个点 ( x , y ) , ( a , b ) (x,y),(a,b) (x,y),(a,b),如果说 ( x , y ) (x,y) (x,y) 支配了 ( a , b ) (a,b) (a,b),这是指 x ≥ a , y ≥ b x\ge a,y\ge b xa,yb
用图形来看就是 ( a , b ) (a,b) (a,b) 坐落在以 ( x , y ) (x,y) (x,y) 为右上角的一个无限的区域内。
给定 n n n 个点的集合,一定存在若干个点,它们不会被集合中的任何一点所支配,这些点叫做极大值点。
编程找出所有的极大点,按照 x x x 坐标由小到大,输出极大点的坐标。

输入描述

输入包括两行,第一行是正整数 n n n,表示是点数,第二行包含 n n n 个点的坐标,坐标值都是整数,坐标范围从 0 ∼ 100 0\sim100 0100,输入数据中不存在坐标相同的点。

输出描述

x x x 轴坐标最小到大的顺序输出所有极大点。
输出格式为: ( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋯   , ( x k , y k ) (x_1,y_1),(x_2,y_2),\cdots,(x_k,y_k) (x1,y1),(x2,y2),,(xk,yk)
注意:输出的每个点之间有 "," 分隔,最后一个点之后没有 ",",少输出和多输出都会被判错。

样例1

输入

5 
1 2 2 2 3 1 2 3 1 4

输出

(1,4),(2,3),(3,1)

提示

对于 50 % 50\% 50% 的数据: 1 ≤ N ≤ 100 1≤N≤100 1N100 0 ≤ X , Y ≤ 100000 0≤X,Y≤100000 0X,Y100000
对于 100 % 100\% 100% 的数据: 1 ≤ N ≤ 500000 1≤N≤500000 1N500000 0 ≤ X , Y ≤ 100000 0≤X,Y≤100000 0X,Y100000

#include <iostream>
#include <algorithm>
using namespace std;

int n;

struct Node {
    int x, y;
}a[250100];

bool cmp(Node aa, Node bb) {
    if (aa.y == bb.y) return aa.x > bb.x;
    return aa.y > bb.y;
}

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i].x >> a[i].y;
    }
    
    sort(a+1, a+n+1, cmp);
    
    int xx = a[1].x;
    cout << "(" << a[1].x << "," << a[1].y << ")";
    for (int i = 1; i <= n; i++) {
        if (a[i].x > xx) {
            cout << ",(" << a[i].x << "," << a[i].y << ")";
            xx = max(xx, a[i].x);
        }
    }
    return 0;
}

3. 奶牛杂技团

题目描述

农夫约翰有 N N N 头奶牛,编号从 1 ∼ N 1\sim N 1N,打算进行叠罗汉的杂技表演。
进行叠罗汉表演时,奶牛站在彼此的身上,形成一个有一定高度的垂直堆叠。
奶牛们正在试图弄清楚它们在这个堆叠中的位置顺序。
奶牛们有自己的重量 W i W_i Wi 和力量 S i S_i Si,一头奶牛倒下的风险等于它身上所有奶牛(不包括它自己)的重量和减去它的力量。
你的任务是确定奶牛的顺序,使奶牛的风险值中的最大值尽可能小。

输入描述

第一行包括一个整数 N N N,表示奶牛的数量,其中 1 ≤ N ≤ 50000 1≤N≤50000 1N50000
接下来 N N N 行,每行两个整数,表示奶牛的重量 W i W_i Wi 和力量 S i S_i Si,其中 1 ≤ W i ≤ 10000 1≤W_i≤10000 1Wi10000 1 ≤ S i ≤ 1 0 9 1≤S_i≤10^9 1Si109

输出描述

输出一个整数,表示最大风险值的最小可能值。

样例1

输入

3
10 3
2 5
3 3

输出

2
#include <iostream>
#include <algorithm>
using namespace std;

long long n, z;
long long m = -2e7, cnt;

struct Node {
	int s, w;
} b[50005];

bool cmp(Node x, Node y) {
	return x.s+x.w < y.s+y.w;
}

int main() {
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> b[i].w >> b[i].s;
	}
	sort(b+1, b+n+1, cmp);
	for(int i = 1; i <= n; i++) {
        m = max(m, (long long)cnt-b[i].s);
		cnt += b[i].w;
	}
	cout << m;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值