中国石油大学秋季组队训练赛15场 F: Hang Gliding (模拟+线段树)

题目链接:点此跳转

题目描述:

The 2020 hang gliding world championships are coming to Florida next spring! (You may think it is odd to hold in Florida a sport that requires mountains, but it turns out that hang gliders can be towed to altitude by other aircraft.) The competition is divided into a set of tasks; completing a task successfully gives a pilot a number of points. Either all points are awarded for a task, or none are. For each task, every pilot has a probability of success. A pilot’s score is the total of all successfully completed tasks at the end of the competition.

This year, the organizing committee couldn’t decide on a reasonable number of tasks, so the time slots for tasks overlap. At any given time, there can be multiple tasks going on, but a pilot may only choose one to be competing in at that time. Each pilot may compete in as many tasks as they want given this constraint. The pilots know their own strengths and weaknesses, and will choose tasks in order to maximize their expected score.

You have been offered free hang gliding lessons if you help with scoring software for the event. Among other things, the committee wants the software to be able to predict the winners ahead of time.

Given a set of tasks, each with a time slot and a point score to be awarded for success, and a list of pilots, each with success probabilities for each task, compute the expected score for each pilot, and report the top 3 expected scores.

解题思路:

先把每个项目按照结束时间从小到大排个序,然后开一个线段树记录一下(l,r) l 时间段之前可以获得的最大期望,然后更新r时间节点的最大期望,不断查询更改即可。

Code:

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 100005;
typedef long long ll;
double indexx[maxn];
int n,m,k;
 
struct XIANG{
    int x,y,id;
    double w;
}a[maxn];
 
struct YONG{
    int id;
    double x;
}b[maxn];
 
struct node{
    int l,r;
    double value;
}tree[maxn<<2];
 
bool cmp(XIANG a,XIANG b){
    return a.y<b.y;
}
 
bool cmp1(YONG u,YONG v){
    return u.x>v.x;
}
 
void push_up(int x){
    tree[x].value=max(tree[x<<1].value,tree[x<<1|1].value);
}
 
void update(int x,double w){
    tree[x].value=max(tree[x].value,w);
}
 
 
void bulid(int x,int l,int r){
    tree[x].l=l;
    tree[x].r=r;
    if(l==r){
        tree[x].value=0;
        return ;
    }
    int mid=(l+r)>>1;
    bulid(x<<1,l,mid);
    bulid(x<<1|1,mid+1,r);
     
    push_up(x);
}
 
 
void change(int x,int p,double w){           //单点更新
    if(tree[x].l==p&&tree[x].r==p){
        update(x,w);
        return ;
    }
     
    int mid=(tree[x].l+tree[x].r)/2;
    if(p<=mid) change(x*2,p,w);
    else  change(x*2+1,p,w);
    push_up(x);
    
}
 
double query(int l,int r,int x){
    if(tree[x].l>=l&&tree[x].r<=r) return tree[x].value;
     
     
    int mid=(tree[x].l+tree[x].r)/2;
    if(r<=mid) return query(l,r,x<<1);
    else if(l>mid) return query(l,r,x<<1|1);
    else return max(query(l,r,x<<1),query(l,r,x<<1|1));
}
 
int main()
{
    scanf("%d%d",&n,&m);
    int cas=0;
     
    for(int i=1;i<=n;i++) {
        scanf("%d%d%lf",&a[i].x,&a[i].y,&a[i].w);
        a[i].id=i;
    }
    sort(a+1,a+1+n,cmp);
     
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            scanf("%lf",&indexx[j]);
        }   
        bulid(1,0,1e4+7);       // 0 ~ 1e4+7 时间段
        for(int j=1;j<=n;j++){
            double yy=query(0,a[j].x,1);        //从0开始查
            change(1,a[j].y,yy+a[j].w*indexx[a[j].id]);

        }
        b[i].x=tree[1].value;
        b[i].id=i;
    }
     
    sort(b+1,b+1+m,cmp1);
    
    for(int i=1;i<=3;i++){
        printf("%d %.2lf\n",b[i].id,b[i].x);
    }
    
     
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值