示例:
输入:
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. Comet OJ 2019 夏季欢乐赛题解

    Comet OJ 2019 夏季欢乐赛题解 我是来骗访问量的 A 完全k叉树 \(n\)个点的完全k叉树的直径. 直接做 B 距离产生美 直接做 C 烤面包片 \(n!!!\mod p\) 显然\(n ...

  2. 61、Spark Streaming:部署、升级和监控应用程序

    一.部署应用程序 1.流程 1.有一个集群资源管理器,比如standalone模式下的Spark集群,Yarn模式下的Yarn集群等. 2.打包应用程序为一个jar包. 3.为executor配置充足 ...

  3. Spark在美团的实践

    https://tech.meituan.com/2016/03/31/spark-in-meituan.html 本文已发表在<程序员>杂志2016年4月期. 前言 美团是数据驱动的互联 ...

  4. JDK 下载相关资料

    所有版本JDK下载地址: http://www.oracle.com/technetwork/java/archive-139210.html 下载账户密码: 2696671285@qq.com Or ...

  5. HTML试题解析

    1.关于CSS为什么会出现Bug说法不正确的是(). (选择二项) A:编写CSS样式时需要考虑在不同浏览器中实现表现一致 B:各大主流浏览器由于不同厂家开发,浏览器使用的内核不同,支持CSS的程度不 ...

  6. leetcode 删除一张表中重复邮箱的数据,并且保留最小id 的 那条

    /* create view testview as SELECT subject,MIN(Id) as id FROM test GROUP BY subject; select * FROM te ...

  7. D3.js的v5版本入门教程(第七章)—— 比例尺的使用

    D3.js的v5版本入门教程(第七章) 比例尺在D3.js中是一个很重要的东西,我们可以这样理解d3.js中的比例尺——一种映射关系,从domain映射到range域(为什么会是domain和rang ...

  8. 2019软工实践_Alpha(事后诸葛亮)

    组长博客 感谢组长 总结思考 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 弥补Powerpoint中模板转换存在的缺陷,完善PPT模板一键转换的功能 ...

  9. 如何SpringBoot项目改为外置Tomcat启动

    正常情况下,我们开发 SpringBoot 项目,由于内置了Tomcat,所以项目可以直接启动,部署到服务器的时候,直接打成 jar 包,就可以运行了 (使用内置 Tomcat 的话,可以在 appl ...

  10. 单点登录(SSO)工作原理

    单点登录(SSO)工作原理 一.单点登录的介绍 单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次 ...