Server
題面: Alice and Bob are working on a new assignment. In this project, they need to access some information on a website and monitor this web site for consistent t days. In others words, in each day, there must be at least one server in work. Luckily, they can rent some servers in the lab. According to the schedule, there are totally N servers being available. The i-th server can be used from the Si-th day to the Ti-th day. However, using the i-th server require Ai dollars. After a long time of persuasion, the administrator of the machine room agree to give Alice and Bob discount. Each server is assigned with a discount number Bi. If the set of servers they want to use is S, they need to pay dollars. As Alice and Bob are preparing the programs on the servers, they want your help to find a way to minimize the cost of servers.
題意:
每條線段都有兩個值a,b,求覆蓋[1,t]的所有端點的 最小值
思路: 經典01分數規劃做法,加上用樹狀數組維護最小值
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int N=1e5+5;
int n,t;
double tree[N];
struct node
{
int a,b,s,t;
}a[N];
bool cmp(node q,node qq)
{
if(q.s==qq.s)
return q.t<qq.t;
return q.s<qq.s;
}
void update(int x,double val)
{
while(x>0)
{
tree[x]=min(tree[x],val);
x-=(x)&(-x);
}
}
double query(int x)
{
if(x==0)
return 0.0;
double res=1e9;
while(x<=t)
{
res=min(res,tree[x]);
x+=(x)&(-x);
}
return res;
}
bool check(double x)
{
double sum=0;
int mx=0;
for(int i=1;i<=n;i++)
{
if(a[i].b*x-a[i].a>=0)
{
sum+=a[i].b*x-a[i].a;
if(a[i].s-1<=mx)
mx=max(mx,a[i].t);
}
}
for(int i=1;i<=t;i++)
tree[i]=1e9;
if(mx==t)
return true;
update(mx,0);
for(int i=1;i<=n;i++)
{
if(a[i].a-a[i].b*x>0)
{
double tmp=query(a[i].s-1);
update(a[i].t,tmp+a[i].a-a[i].b*x);
}
else
{
double tmp=query(a[i].s-1);
update(a[i].t,tmp);
}
}
return sum>=query(t);
}