链接:https://ac.nowcoder.com/acm/contest/887/C
来源:牛客网

时间限制:C/C++ 3秒,其他语言6秒
空间限制:C/C++ 65536K,其他语言131072K
64bit IO Format: %lld
题目描述
The Wow village is often hit by wind and sand,the sandstorm seriously hindered the economic development of the Wow village.
There is a forest in front of the Wowo village, this forest can prevent the invasion of wind and sand. But there is a rule that the number of tallest trees in the forest should be more than half of all trees, so that it can prevent the invasion of wind and sand. Cutting down a tree need to cost a certain amount of money. Different kinds of trees cost different amounts of money. Wow village is also poor.
There are n kinds of trees. The number of i-th kind of trees is PiP_iPi​, the height of i-th kind of trees is HiH_iHi​, the cost of cutting down one i-th kind of trees is CiC_iCi​.

(Note: “cutting down a tree” means removing the tree from the forest, you can not cut the tree into another height.)

输入描述:

The problem is multiple inputs (no more than 30 groups).
For each test case.
The first line contines one positive integers n(1≤n≤105)n (1 \leq n \leq 10^5)n(1≤n≤105),the kinds of trees.
Then followed n lines with each line three integers Hi(1≤Hi≤109)H_i (1 \leq H_i \leq 10^9)Hi​(1≤Hi​≤109)-the height of each tree, Ci(1≤Ci≤200)C_i (1 \leq C_i \leq 200)Ci​(1≤Ci​≤200)-the cost of cutting down each tree, and Pi(1≤Pi≤109)P_i(1 \leq P_i\leq 10^9)Pi​(1≤Pi​≤109)-the number of the tree.

输出描述:

For each test case, you should output the minimum cost.

示例1
输入

2
5 1 1
1 10 1
2
5 1 2
3 2 3

输出

1
2

题意:输入n,有n种树,然后n行,每行3个数字,描述一种树的高度,砍掉一棵这种的树需要花费的代价,这种树的总数目。现在你可以砍掉一些树(可以某种类别只砍掉其中几棵),使得剩余的树中高度最高的树的数目要严格大于其他树的数目,怎么砍使得代价最小输出这个代价。

题解:数据范围真的很重要,n=1e5,最极端情况就是1e5种高度,C++时间限制为4s,那么就暗示着可以把分别这n种高度视为最高高度进行遍历找最小代价,当高度为h时,大于h的所有树必须全部砍掉,然后用sum1[maxn]记录前缀和,sum1[h]也就表示砍掉所有大于h的数目的代价,同时我们得判断当前的剩余的树的数目有没有达到题目要求,然后再定义两个数组num1[maxn]记录砍掉大于h高度的树的总数目,num2[maxn]表示高度为h的树的总数目,这样再用高度进行遍历做判断时就比较方便了。

但是问题就来了,怎么计算砍掉小于h高度的树的代价?
这里有两个难点:1.价值得保证从小到大找 2.砍掉的树的高度不能高于h
因为我们是用高度h进行遍历寻找,再找砍掉小于h的树的代价就不能二重循环遍历了,于是乎,再观察题目,你会发现每种树的3个属性:h,c,p,h和p的数据范围都很大在1-1e9之间,但是c莫名只有1-200,说明c这里有点问题,我们就着重考虑c的关系,因为c最大200,是否每次遍历h找小于h高度的树代价时就直接二重循环,时间复杂度O(200*n)也不会超时,那么我们定义一个cost[300],表示价格为c的树的数目为cost[c],那么肯定会有疑问,同一个价格混杂了很多不同高度的树,我怎么从价格c的树中找出高度低于h的树,这里就需要巧妙处理一下,我们将树的高度进行排序处理,在遍历时h从低到高找,然后我们定义一个动态数组h[maxn],储存同一高度的不同树,然后一开始将cost清空,每次遍历结束h后,就把所有高度为h的树通过动态数组h[h]加入到cost中,也就是(i表示树的高度):
for(int j=0;j<h[i];j++)
cost[h[i][j].c]+=h[i][j].p;
留给下一个h+1判断使用,然后这样就很巧妙的保证了在遍历找花费的时候,cost数组中绝对不会出现大于h的树的数据,然后题目完美解决。

最后:高度数据比较大,进行离散化处理

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+100;
struct Node{int h,c;ll p;
}a[N];
//按树的高度进行排序
bool cmp(Node a1,Node a2)
{return a1.h<a2.h;
}
//用来进行离散化判断某个高度是否出现过
map<int,int>vis;
//定义动态数组储存高度
vector<Node>h[N];
//定义砍掉大于h的树的代价数组sum1,砍掉大于h的树的总数目num1,高度为h的树的数目num2
ll sum1[N],num1[N],num2[N];
//定义小于高度h的花费
ll cost[300];
int main()
{int n;
//  freopen("data.txt","r",stdin);// 按顺序读入(仅此一行)while(~scanf("%d",&n)){ll ans=0;for(int i=1;i<=n;i++){scanf("%d%d%lld",&a[i].h,&a[i].c,&a[i].p);h[i].clear();h[i+1].clear();//ans记录总的树的数目 ans+=a[i].p;}sort(a+1,a+n+1,cmp);int sign=0;vis.clear();//离散化并把对应的高度的树储存入动态数组 for(int i=1;i<=n;i++){if(vis[a[i].h]==0){vis[a[i].h]=1;++sign;h[sign].push_back(a[i]);}else{h[sign].push_back(a[i]);}}memset(sum1,0,sizeof(sum1));memset(num1,0,sizeof(num1));memset(num2,0,sizeof(num2));//开始处理砍掉高于h的树的对应数据 for(int i=sign;i>=1;i--){sum1[i]+=sum1[i+1];num1[i]+=num1[i+1];for(int j=0;j<h[i+1].size();j++){sum1[i]+=(h[i+1][j].c*h[i+1][j].p);num1[i]+=h[i+1][j].p;}for(int j=0;j<h[i].size();j++)num2[i]+=h[i][j].p;}memset(cost,0,sizeof(cost));ll mi=1e18;for(int i=1;i<=sign;i++){//num表示剩下的高度小于h的树比高度为h的树数目差 ll num=ans-num1[i]-2*num2[i]+1;ll sum2=0;if(num>0){ for(int j=1;j<=200;j++){if(num>=cost[j]){num-=cost[j];sum2+=(cost[j]*j);}else{sum2+=(num*j);num=0;break;}}}mi=min(mi,sum1[i]+sum2);//把当前高度的树的数据加入cost中给下一高度使用 for(int j=0;j<h[i].size();j++){cost[h[i][j].c]+=h[i][j].p;}}printf("%lld\n",mi);}}
/*
4
5 1 1
7 10 1
4 7 2
3 2 3
*/

2019牛客网暑期多校赛第七场C题Governing sand --思维+前缀和相关推荐

  1. 2019牛客网暑假多校训练第四场 K —number

    链接:https://ac.nowcoder.com/acm/contest/884/K 来源:牛客网 题目描述 300iq loves numbers who are multiple of 300 ...

  2. 牛客网提高组模拟赛第七场 T3 洞穴(附bitset介绍)

    就是DP. 我们可以很简单的想到要枚举中间点,进行边数的转移. 但是因为边长数据范围很大,所以我们考虑log的倍增. 状态设计为\(dp[i][j][k]\),为从节点\(i\)走\(2^k\)步能否 ...

  3. 牛客网暑期ACM多校训练营(第十场)F.Rikka with Line Graph

    牛客网暑期ACM多校训练营(第十场)F.Rikka with Line Graph 做法:\(G'\) 中的对应原图两条边(a,b) (c,d)的最短路为: \[ w[a][b] + w[c][d] ...

  4. 牛客网暑期ACM多校训练营(第九场)

    牛客网暑期ACM多校训练营(第九场) A. Circulant Matrix 做法:看到下标 \(xor\) 这种情况就想 \(FWT\),可是半天没思路,于是放弃了..其实这个 \(n\) 疯狂暗示 ...

  5. 牛客网暑期ACM多校训练营(第五场)

    牛客网暑期ACM多校训练营(第五场) A. gpa 二分答案,然后就转化为是否满足 \(\frac {\sum s[i]c[i]}{\sum s[i]} ≥ D\), \(\sum s[i]c[i] ...

  6. 牛客网暑期ACM多校训练营(第三场)

    牛客网暑期ACM多校训练营(第三场) A. PACM Team 01背包,输出方案,用bool存每种状态下用的哪一个物品,卡内存.官方题解上,说用char或者short就行了.还有一种做法是把用的物品 ...

  7. 牛客网暑期ACM多校训练营(第一场)

    牛客网暑期ACM多校训练营(第一场) A. Monotonic Matrix 考虑0和1的分界线,1和2的分界线,发现问题可以转化为两条不互相穿过的路径的方案数(可重叠),题解的做法就是把一条路径斜着 ...

  8. 牛客网暑期ACM多校训练营(第十场)D Rikka with Prefix Sum

    链接:https://www.nowcoder.com/acm/contest/148/D 来源:牛客网 题目描述 Prefix Sum is a useful trick in data struc ...

  9. 牛客网暑期ACM多校训练营(第三场)A.PACM Team(多重01背包)

    链接:https://www.nowcoder.com/acm/contest/141/A 来源:牛客网 题目描述 Eddy was a contestant participating in ACM ...

最新文章

  1. grep 在HP-UX下的递归查找
  2. Ajax异步XMLHttpRequest对象
  3. 用jQuery设置多个css样式
  4. mac终端一次命令在多个虚拟机执行_Windows给力!可以扔掉Linux虚拟机了!
  5. 慕学在线网0.4_xadmin后台管理
  6. windows c++ 原子操作_高分辨质谱数据处理操作篇
  7. 安装xmanager linux系统,安装Xmanager登陆Linux操作系统[图文]
  8. Python中提供的各种队列结构
  9. egg 完整实例 增删改查MongoDB,websocket
  10. 父与子python第三版,父与子的编程之旅 与小卡特一起学Python 第3版(全彩印刷)...
  11. UG10.0如何导出CAD图
  12. 音频LINE OUT,LINE IN接口
  13. 理财趣事:要想财富滚滚来 先学普京打野猪
  14. vscode配置python环境以及使用json文件配置默认解释器、代码自动保存、pydesigner、kite
  15. html浏览器标题闪动,如何实现网页标题的闪动提示
  16. 条码标签设计软件Nicelabel使用方法
  17. java ntohl 类似函数_关于 htonl 和 ntohl 的实现
  18. 【python初级】os.path.isfile(path)判断路径是否为文件
  19. 2020最全的BAT大厂面试题整理改版3面直接拿到offer
  20. FL Studio21水果体验尝鲜版音乐宿主程序FL2023

热门文章

  1. Conllection
  2. Android ListView 设置分割线的设置
  3. 企业电子招投标采购系统源码之首页设计
  4. 基于matlab的螺线管仿真,基于COMSOL Multiphysics恒流螺线管的电磁场仿真分析
  5. \t\t有一种女人嫁给谁都幸福
  6. 关于DNS攻击那点事儿~ (DNS劫持 vs ISP劫持)
  7. Spark三种部署方式
  8. win7注册服务器错误代码,鲜为人知的Windows7系统错误代码大全汇总
  9. 安徽理工大学计算机学院蒋群,计算机学院举办优秀毕业生讲座
  10. 网络数据抓取赋能商业分析与业务增长