示例:
输入:
2
5 1 1
1 10 1
2
5 1 2
3 2 3
输出:
1
2

题意:n种树,第i种树有P[i]颗,砍掉每颗树的代价是C[i], 高度是H[i]。需要用最小的花费砍掉一些树,让最高的树超过一半。

题解:按高度分类,从小到大枚举最大高度,比当前枚举的高度 h 要高的,一定删,比它小的,如果删前 ? 小的。

贪心代码:

 #include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxx=1e5+;
struct node{
ll h,v,p;
bool operator<(const node&a)const{
return h<a.h;
}
}tree[maxx];
ll B[],arr[maxx],pre[maxx];//B储存已经遍历过的树在该价值的数量,arr储存第i高及比第i高的树都被砍掉的花费,pre储存第i高树矮的树的数量
int main()
{
ll n;
while(~scanf("%lld",&n)){
memset(B,,sizeof(B));
for(int i=;i<=n;i++)scanf("%lld%lld%lld",&tree[i].h,&tree[i].v,&tree[i].p);
sort(tree+,tree++n);//从低到高排序高度
arr[n+]=;
for(int i=n;i>=;i--)arr[i]=arr[i+]+tree[i].v*tree[i].p;
pre[]=;
for(int i=;i<=n;i++)pre[i]=pre[i-]+tree[i].p;
ll ans=1e18;
for(int i=,j=;i<=n;i=j){//从小到大枚举最大高度
while(j<=n&&tree[j].h==tree[i].h)j++;
ll sums=;
for(int k=i;k<j;k++)sums+=tree[k].p;
ll cost=arr[j];
if(sums<=pre[i-]){//如果第i高的树的数量小于比它矮的树的数量,即将价值数组进行从小到大处理
ll need=pre[i-]-sums+;
for(int t=;t<=;t++){
if(B[t]<=need){
cost+=B[t]*t;
need-=B[t];
}else{
cost+=need*t;
break;
}
}
}
ans=min(ans,cost);
for(int k=i;k<j;k++)B[tree[k].v]+=tree[k].p;
}
printf("%lld\n",ans);
}
return ;
}

主席树代码:

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int maxx=2e5+;
int tot;
struct Node{
LL h,v,p;
bool operator <(const Node &a)const
{
return a.h>h;
}
}tree[maxx];
struct node{
LL l,r,sum,num;
}p[maxx*];
LL v[maxx],root[maxx];
LL update(LL rot,LL l,LL r,LL pos,LL num)//建立主席树
{
LL book=++tot;
p[book]=p[rot];//传递上一颗主席树的性质进行修改
p[book].num+=(LL)num;
p[book].sum+=(LL)pos*(LL)num;
if(l==r) return book;
LL mid=l+r>>;
if(pos<=mid) p[book].l=update(p[rot].l,l,mid,pos,num);
else p[book].r=update(p[rot].r,mid+,r,pos,num);
return book;
}
LL query(LL rot,LL l,LL r,LL num)//查询
{
if(l==r) return (LL)l*(LL)num;
LL ans=p[p[rot].l].num;
LL mid=l+r>>;
if(num<=ans) return query(p[rot].l,l,mid,num);
else
{
return p[p[rot].l].sum+query(p[rot].r,mid+,r,num-ans);
}
}
int main()
{
int n;
while(~scanf("%lld",&n)){
tot=;
memset(v,,sizeof(v));
for(int i=;i<=n;i++){
scanf("%lld%lld%lld",&tree[i].h,&tree[i].v,&tree[i].p);
}
sort(tree+,tree+n+);
for(int i=;i<=n;i++)
v[i]=v[i-]+tree[i].p;
for(int i=;i<=n;i++){
root[i]=update(root[i-],,,tree[i].v,tree[i].p);//主席树记录每种树的根节点
}
LL Minn=1e18,moneys=;
for(int i=n;i>=;i--){
LL treenum=,sums=;
while(tree[i].h==tree[i-].h){
treenum+=tree[i].v*tree[i].p;
sums+=tree[i].p;
i--;
}
treenum+=tree[i].v*tree[i].p;
sums+=tree[i].p;
LL Smoney=;
if(v[i-]>=sums)Smoney=moneys+query(root[i-],,,v[i-]-sums+);//如果第i高的树的数量小于比它矮的树的数量,查询前i-1种树中的需要砍的树的花费
else Smoney=moneys;
Minn=min(Minn,Smoney);
moneys+=treenum;//记录比第i种树高的树的砍掉的花费
}
printf("%lld\n",Minn);
}
return ;
}

Governing sand(主席树/贪心)(2019牛客暑期多校训练营(第七场))的更多相关文章

  1. 2019牛客暑期多校训练营(第九场)H Cutting Bamboos(主席树+二分)

    题意:n个竹子,有高度,q次询问,询问之间是独立的,每次查询输入l,r,x,y代表砍区间[l,r]]内的竹子砍y次,最后一次要砍成0,每次砍掉的总长度相同,问第x次砍的高度是多少. 既然每次要求砍掉的 ...

  2. 2019牛客暑期多校训练营(第九场)A:Power of Fibonacci(斐波拉契幂次和)

    题意:求Σfi^m%p. zoj上p是1e9+7,牛客是1e9:  对于这两个,分别有不同的做法. 前者利用公式,公式里面有sqrt(5),我们只需要二次剩余求即可.     后者mod=1e9,5才 ...

  3. 2019牛客暑期多校训练营(第一场)A题【单调栈】(补题)

    链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 题目描述 Two arrays u and v each with m distinct elem ...

  4. 2019牛客暑期多校训练营(第一场) B Integration (数学)

    链接:https://ac.nowcoder.com/acm/contest/881/B 来源:牛客网 Integration 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 5242 ...

  5. 2019牛客暑期多校训练营(第一场) A Equivalent Prefixes ( st 表 + 二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A 来源:牛客网 Equivalent Prefixes 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/ ...

  6. 2019牛客暑期多校训练营(第二场)F.Partition problem

    链接:https://ac.nowcoder.com/acm/contest/882/F来源:牛客网 Given 2N people, you need to assign each of them ...

  7. 2019牛客暑期多校训练营(第一场)A Equivalent Prefixes(单调栈/二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 Two arrays u and v each with m distinct elements ...

  8. [状态压缩,折半搜索] 2019牛客暑期多校训练营(第九场)Knapsack Cryptosystem

    链接:https://ac.nowcoder.com/acm/contest/889/D来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言52428 ...

  9. DP+线段树维护矩阵(2019牛客暑期多校训练营(第二场))--MAZE

    题意:https://ac.nowcoder.com/acm/contest/882/E 给你01矩阵,有两种操作:1是把一个位置0变1.1变0,2是问你从第一行i开始,到最后一行j有几种走法.你只能 ...

  10. Points Division(线段树+DP)2019牛客暑期多校训练营(第一场)

    题意:https://ac.nowcoder.com/acm/contest/881/I 给你n个平面上的点,每个点有a.b两个权值,现在让你划分成两个区域(要求所有A集合里的点不能在任何B集合里的点 ...

随机推荐

  1. 洛谷 P3469 [POI2008]BLO-Blockade 题解

    一道经典的割点例题,用size数组记录该子树有多少个节点,sum是这棵搜索树上有多少个节点,sum*(n-sum-1)是将点删掉后的数对数量. #include<iostream> #in ...

  2. vue-cli使用笔记

    安装nodejs 安装vue-clinpm install -g vue-cli 使用vue-cli初始化项目vue init webpack my-project 进到目录cd my-project ...

  3. Spyder汉化问题

    首先感谢李增海大神,以下内容来源于http://www.lizenghai.com 必备条件 1.已安装Spyder 2.Spyder版本在3.X以上 Spyder安装: 1.anaconda下,co ...

  4. Awesome Go精选的Go框架,库和软件的精选清单.A curated list of awesome Go frameworks, libraries and software

    Awesome Go      financial support to Awesome Go A curated list of awesome Go frameworks, libraries a ...

  5. P1099 树网的核——模拟+树形结构

    P1099 树网的核 无根树,在直径上找到一条长度不超过s的路径,使得最远的点距离这条路径的距离最短: 首先两遍dfs找到直径(第二次找的时候一定要吧father[]清零) 在找到的直径下枚举长度不超 ...

  6. PL/SQL Developer插入数据到数据库出现数据中文乱码

    问题描述: 使用PL/SQL Developer往Oracle数据库插入数据,出现中文乱码! 解决办法: 1.执行脚本 select userenv('language') from dual; 结果 ...

  7. MongoDB 数据库创建删除

    在MongoDB数据库里面是存在有数据库的概念,但是没有模式(所有的信息都是按照文档保存的),保存数据的结构就是JSON结构,只不过在进行一些数据处理的时候才会使用到MongoDB自己的一些操作符号 ...

  8. 在js中添加HTML类样式

    有时候需要给元素添加类样式,但又要保留之前的类,可以使用element.classList.add("类名");

  9. kubernetes监控终极方案-kube-promethues

    kube-promethues简介 前面我们学习了Heapster+cAdvisor方式监控,这是Prometheus Operator出现之前的k8s监控方案.后来出现了Prometheus Ope ...

  10. 【软工实践】Alpha冲刺(6/6)

    链接部分 队名:女生都队 组长博客: 博客链接 作业博客:博客链接 小组内容 恩泽(组长) 过去两天完成了哪些任务 描述 tomcat的学习与实现 服务器后端部署,API接口的beta版实现 后端代码 ...