Server 01分數規劃+樹狀數組 HDU6240

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 iSAi/iSBi∑_{i∈S}Ai/∑_{i∈S}Bi 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]的所有端點的iSAi/iSBi∑_{i∈S}Ai/∑_{i∈S}Bi 最小值
思路: 經典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);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章