示例:
输入:
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 ;
}

最新文章

  1. PYTHON 写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者
  2. 如何让JQuery报错-遁地龙卷风
  3. 服务器如何处理http请求
  4. 一个奇怪的网络故障 默认网关为0.0.0.0(Windows)
  5. 在线判题 (模拟)http://202.196.1.132/problem.php?id=1164
  6. Umbraco官方技术文档 中文翻译
  7. 如何从代码层防御10大安全威胁中的 Xpath Injection?
  8. bzoj2724
  9. hdu2082:简单母函数
  10. EF数据迁移(当模型改变时更新数据库)
  11. WindowsService开发遇到的问题
  12. emacs24 颜色主题设置
  13. 10.2 Vue 环境安装
  14. python中的包与模块
  15. 【转】宽带路由器应用(三)—ARP欺骗防护功能的使用
  16. SAP S/4 1610 IDES + HANA 2.0 安装
  17. C语言中宏定义(#define)时do{}while(0)
  18. List去重问题
  19. Nutch源码阅读进程5
  20. HDU 3849 By Recognizing These Guys, We Find Social Networks Useful(双连通)

热门文章

  1. 检验多个xsd的xml是否合法
  2. Mscordacwks.dll/SOS.dll 调试归档
  3. WinDbg常用命令系列---内存查看d*
  4. 使用go-mysql-server 开发自己的mysql server
  5. PHP正则表达式提取html超链接中的href地址
  6. Hungry Canadian
  7. 使用python3完成人脸识别
  8. 关于Django中的数据库操作API之distinct去重的一个误传
  9. window 10 打开某个 窗口常用命令
  10. opencv yuvNV21转RGB