首页 > 其他分享 >P6346 题解

P6346 题解

时间:2023-10-18 22:36:50浏览次数:33  
标签:node ch return int 题解 pq know P6346

题目大意

如果 \(\texttt{Kevin}\) 想和第 \(i\) 个人交朋友,要么需要认识 \(a_i\) 个人,要么付出 \(b_i\) 的代价,他让你使 \(\texttt{Kevin}\) 与所有的人交朋友。

解题思路

如果想水到 \(15\) 分,也就是所有 \(b_i\) 都等于 \(1\) 的情况,那我们可以直接排个序,然后遍历一下每一个人,如果目前所认识的人数小于 \(a_i\),那就付出 \(b_i\) 的代价,否则跳过。

排序部分代码:

bool cmp(node x, node y) {
	if(x.a != y.a) {
    	return x.a < y.a;
    }
    return x.b < y.b;
}

处理部分代码:

for(int i = 1; i <= n; i++) {
	if(know_cnt /*目前交的朋友的数量*/ < x[i].a) {
    	ans /*付出的最小代价*/ += x[i].b;
    }
    know_cnt++;
}

但我们的目标是 \(100\) 分,如果已经交了 \(i\) 个朋友,正在交 \(j\) 这个朋友,那么 \(j\) 的取值可以为 [0,n-1],因为朋友关系是唯一的。而想要免费交到,就需要 \(j\) 的取值在 [a[i].x,n-1] 内。贪心选取最大值,将数组以 a[i].y 从大到小排序。

但是这样的话两重循环过不了,所以可以用优先队列稍加优化(即 priority_queue)。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 5;
struct node {
	int x, y;
} a[N];
int n;
int tot = 0;
int sum = 0, ans = 0, know_cnt = 0;
priority_queue<int, vector<int>, greater<int> > pq;
inline ll read() {
	ll x = 0, f = 1;
	char ch = getchar();
	while (!isdigit(ch))
	{
		if (ch == '-') 
			f = -1;
		ch = getchar();
	}
	while (isdigit(ch))
	{
		x = (x << 1) + (x << 3) + (ch ^ 48);
		ch = getchar();
	}
	return x * f;
}
inline void write(ll x) {
	if (x < 0) putchar('-'), x = -x;
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
inline bool cmp(node x, node y) {
	return x.x > y.x;
}
int main() {
	n = read();
	for(int i = 1; i <= n; i++) {
		int t1 = read(), t2 = read();
		sum += t2;
		if(t1 < n) {
			a[++tot] = {t1, t2};
		}
	}
	sort(a + 1, a + tot + 1, cmp);
	for(int i = 1; i <= tot; i++) {
		if(n - a[i].x > know_cnt) {
			pq.push(a[i].y);
			know_cnt++;
		} else {
			if(n - a[i].x == know_cnt && !pq.empty()) {
				if(a[i].y > pq.top()) {
					pq.pop();
					pq.push(a[i].y);
				}
			}
		}
	}
	while(!pq.empty()) {
		ans += pq.top();
		pq.pop();
	}
	write(sum - ans);
	return 0;
}
``

标签:node,ch,return,int,题解,pq,know,P6346
From: https://www.cnblogs.com/cyf1208/p/17773526.html

相关文章

  • P2198 题解
    解题思路激光塔一定在最后。\(f_{i,j}\)表示前\(i\)个位置放\(j\)(\(j\lei\))个放射塔,那么\(i-j\)个干扰塔的伤害。若第\(i\)个位置放放射塔:\(f_{i,j}=f_{i-1,j-1}+(j-1)\timesg\times[t+b\times(i-j)]\)若第\(i\)个位置放干扰塔,也就是\(j<i\):\(f_{i,j}=\max\{f_{i-......
  • P7974 题解
    解题思路首先可以确保每一次列的方向一定不会与\(s\)到\(t\)的方向相反。不妨设\(l=\min\{s,t\}\),\(r=\max\{s,t\}\)。对于每次移动,所花体力值如下:显然,从\(l\)到\(r\),一定要翻过\([l,r]\)间最高的一个,区间最大我们毫不犹豫地选择ST表,然后我们思考一下,令\(h_x=\m......
  • P4814 题解
    解题思路对于每条边\((u,v)\),权值为\(w\),假设存在一条经过这一条边的路径,其最短距离为\(a\)到\(u\)的最短路加上\(v\)到\(b\)的最短距离加上\(w\),若这个值都大于\(d\),则不可能关闭这条边。由于边权非负,所以可采用dijkstra来处理最短路。因为为有向边,所以可以再建......
  • C++常见入门题题解
    前言因为本人目前比较菜,所以给出的题解都是按照自己的学习进度来的,所以难度是一个循序渐进的过程,由于本人水平有限,望读者能够指出谬误,共同进步。回文数输出#include<bits/stdc++.h>//万能头usingnamespacestd;intmain(void){vector<int>font;//定义一个整型的向......
  • 题解 CF1651F【Tower Defense】
    题解CF1651F【TowerDefense】problem一个塔防游戏。一共有\(n\)个塔按\(1\simn\)的顺序排成一列,每座塔都有魔力容量\(c_i\)和魔力恢复速率\(r_i\)。对于一座塔\(i\),每过一秒它的魔力\(m_i\)会变为\(\min(m_i+r_i,c_i)\)。每座塔初始时满魔力。一共有\(q\)个......
  • 【题解 CF840C & P4448】 On the Bench & 球球的排列
    OntheBench题面翻译给定一个序列\(a(a_i\le10^9)\),长度为\(n(n\le300)\)。试求有多少\(1\)到\(n\)的排列\(p_i\),满足对于任意的\(2\lei\len\)有\(a_{p_{i-1}}\timesa_{p_i}\)不为完全平方数,答案对\(10^9+7\)取模。题目描述Ayearagoonthebenchinpu......
  • P9506 题解
    blog。Firstsolution/kx。容易想到断环成链。打开标签发现是DP,于是就可以DP了。code,时间复杂度\(O(\text{能过})\)。......
  • 算法笔记-有效括号序列题解
    描述给出一个仅包含字符'(',')','{','}','['和']',的字符串,判断给出的字符串是否是合法的括号序列。括号必须以正确的顺序关闭,"()"和"()[]{}"都是合法的括号序列,但"(]"和"([)]"不合法。数据范围:字符串长度0≤n≤10000要求:空间复杂度O(n),时间复杂......
  • NOIP2018PJ T3 摆渡车(2023.10第二版题解)
    题目链接 题意:时间轴上分布着$n$位乘客($1\len\le500$),$i$号乘客的位置为$t_i$(0\let_i\le4\times10^6),用互相距离不小于$m$的车次将时间轴分为若干部分,并管辖以自己为右端点的这个区间(除了第一趟车包括$0$,其他车次左开右闭),求最小费用和。每个车次的费用来自:管辖区间内所......
  • AT_arc100_b 题解
    题意这道题是让我们把一段区间分成四个不为空的连续子序列,并算出每个区间的和,最后用四个和的最大值减去最小值,算出最终答案。分析大家首先想到的肯定是暴力法用三个循环枚举四个区间,对于每一个区间,在单独算和,这样的时间复杂度$O(n^4)$,肯定会超时。现在我们进行优化:最后求和的......