示例:
输入:
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. BZOJ 5305: [Haoi2018]苹果树 组合计数

    一定要注意要乘阶乘,细节很多. code: #include <bits/stdc++.h> #define ll long long #define setIO(s) freopen(s ...

  2. WinDbg常用命令系列---显示数据类型dt/dtx

    dt (Display Type) dt命令显示有关局部变量.全局变量或数据类型的信息.这可以显示有关简单数据类型以及结构和联合的信息. 用户模式下: dt [-DisplayOpts] [-Sear ...

  3. CSS3背景图片(多重背景、起始位置、裁剪、尺寸)

    一.多重背景图片 ①CSS3允许我们在一个元素上添加多个图片 ②多重背景可以把多个图片资源添加到background属性上,用逗号隔开,然后用background-position把他们定位到你想要的 ...

  4. 如何学习uni-app?

    uni-app 是一个使用 Vue.js 开发跨平台应用的前端框架. 开发者通过编写 Vue.js 代码,uni-app 将其编译到iOS.Android.微信小程序.H5等多个平台,保证其正确运行并 ...

  5. C博客作业01--分支丶顺序结构

    1.本章学习总结 1.1学习内容总结 分支结构 if else-if语句与switch语句都具有选择判断的功能,但是在使用时又有所区别,按题目的不同要求与题意选择不同语句. if else-if语句表 ...

  6. Interesting Vertices

    Interesting Vertices(前向星+思维+dfs回溯) 参考博客:https://blog.csdn.net/I_believe_CWJ/article/details/10247201 ...

  7. python设计模式---绪论

    1.程序只是一个工具,只知道使用工具就有价值的时代正在过去:现在对工作质量.开发速度及完美程度都很重要了.当前主要的问题是对工具的充分利用,在生活的方方面面,简单任务之所以简单是由于这些任务不需要特殊 ...

  8. Java Spring 使用 Redis

    在 Java 中使用 Redis 需要使用 Jedis.jar github 页面 https://github.com/xetorthio/jedis javadocs http://xetorth ...

  9. 东站七雄保C位!论三线楼市网红板块的自我修养

    不对!东站板块才是伍家岗的C位.这里有东站七雄! 前些天发了一篇城东C位之路的文章,居然引发了诸葛说房聊天群内大佬的激烈纷争.公说公有理婆说婆有理,一时争的是不可开交,大有约架之势.所以我决定提前写& ...

  10. windows如何查看jdk的安装目录

    1.检查电脑上是否安装了JDK可以在cmd窗口输入java -version查看是否需安装了JDK 2.查看JDK的安装目录 一种是在cmd窗口输入java -verbose,查看最后一行即为JDK安 ...