HDU 6240 01 Fractional Planning

This is the K question of CCPC Harbin. At that time, I heard that the THU card question girls team next door said that it was a 01 score plan, and I gave up before I learned it. Later, I found that this thing is quite stupid. I took out the BB today and quickly became AC.
The meaning of the question: Select a part from a bunch of [si, ti] intervals to completely cover [1, T], each interval has two weights ai bi, and the selected interval is required to be aibi the minimum value of .
Practice: first refer to the article of the fjzzq boss https://www.cnblogs.com/zzqsblog/p/5450361.html , find that the 01 fraction plan is to multiply the denominator after the two-point answer, so that aibimid is positive (negative), this only needs to be a i - b i m i d As a new weight, it can be greedy from large to small. Then in this question, after the two-point answer, obviously all the positive parts have to be taken out, so it becomes how to cover the remaining interval with the least cost. I sort the line segments by the left endpoint and then use bit to maintain dp. Done. This complexity has two logs, but considering the time limit of 10s, it is still very easy to AC, which takes 2652ms.
Code:

#include <bits/stdc++.h>
using namespace std;
const int maxn=100007;
int n, t;
struct node {
    int s, t, a, b;
    bool tag;
}rec[maxn];
bool cmp(node a, node b){
    if(a.s==b.s)return a.t<b.t;
    return a.s<b.s;
}
bool vis[maxn];
double c[maxn];
int lowbit(int x){
    return x&(-x);
}
void update(int x, double num){
    while(x){
        c[x]=min(c[x], num);
        x-=lowbit(x);
    }
}
double query(int x){
    if(x==0)return 0;
    double ans=1e9;
    while(x<=t){
        ans=min(ans, c[x]);
        x+=lowbit(x);
    }
    return ans;
}
bool check(double mid){
    double sum=0;
    int r=0;
    for(int i=1;i<=t;i++){
        c[i]=1e9;
    }
    for(int i=1;i<=n;i++){
        if(rec[i].b*mid-rec[i].a>0){
            sum+=rec[i].b*mid-rec[i].a;
            rec[i].tag=true;
            if(rec[i].s-1<=r){
                r=max(r, rec[i].t);
            }
        }
        else rec[i].tag=false;
    }
    if(r==t)return true;
    update(r, 0);
    for(int i=1;i<=n;i++){
        if(!rec[i].tag){
            double from=query(rec[i].s-1);
            update(rec[i].t, from+rec[i].a-rec[i].b*mid);
        }
        else {
            double from=query(rec[i].s-1);
            update(rec[i].t, from);
        }
    }
    return sum>=query(t);
}
int main(){
    int T;
    scanf("%d", &T);
    while(T--){
        scanf("%d%d", &n, &t);
        for(int i=1;i<=n;i++){
            scanf("%d%d%d%d", &rec[i].s, &rec[i].t, &rec[i].a, &rec[i].b);
        }
        sort(rec+1, rec+1+n, cmp);
        double l=0, r=1001;
        int tim=30;
        for(int i=1;i<=tim;i++){
            double mid=(l+r)/2;
            if(check(mid))r=mid;
            else l=mid;
        }
        printf("%.3f\n", l);
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325945942&siteId=291194637