求助斜率优化+二分
查看原帖
求助斜率优化+二分
230804
Durancer楼主2021/5/15 15:39

这是题目的整体代码:

#include<cmath>
#include<map>
#define int long long 
using namespace std;
const int N=3e5+9;
int f[N];//前i个分成若干个的小收益
int s[N];//时间前缀和
int e[N];//费用系数前缀和
int q[N];
int t;//开机花费时间 
int n;
int head=1,tail=0;
int read()
{
	int f=1,x=0;
	char s=getchar();
	while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
	while(s>='0'&&s<='9'){x=(x<<1)+(x<<3)+(s^'0');s=getchar();}
	return f*x;
}
long double Y(int j)
{
	return (long double)f[j]-(long double)e[j]*(long double)t;
}
long double X(int j)
{
	return (long double)e[j];
}
long double slope(int i,int j)
{
	return X(j)==X(i)?(Y(j)>=Y(i)?1e18:-1e18):(long double)(Y(j)-Y(i))/(X(j)-X(i));
}
void DP()
{
	for(int i=1;i<=n;i++)
	{
		int l=head;
		int r=tail;
		int pos=0;
		while(l<r)
		{
			int mid=(l+r)>>1;
			if(slope(q[mid],q[mid+1])<=s[i])
			{
				pos=mid+1;
				l=mid+1;
			}
			else r=mid;
		}
		f[i]=f[q[pos]]+s[i]*e[i]-s[i]*e[q[pos]]+t*e[n]-t*e[q[pos]];
		while(head<tail and slope(q[tail-1],q[tail])>slope(q[tail],i))
			tail--;
		q[++tail]=i; 
	}
}
signed main()
{
	n=read();
	t=read();
	for(int i=1;i<=n;i++)
	{
		s[i]=s[i-1]+read();
		e[i]=e[i-1]+read(); 
	}
	q[++tail]=0;
	DP();
	printf("%lld\n",f[n]); 
}

写了两种不同的二分方法:

一、90pts。

int l=head;
		int r=tail;
		int pos=0;
		while(l<=r)
		{
			int mid=(l+r)>>1;
			if(slope(q[mid-1],q[mid])<=s[i])
			{
				pos=mid;
				l=mid+1;
			}
			else r=mid-1;
		}
		f[i]=f[q[pos]]+s[i]*e[i]-s[i]*e[q[pos]]+t*e[n]-t*e[q[pos]];

二、100pts

int l=head;
		int r=tail;
		if(l==r) goto Here;
		while(l<r)
		{
			int mid=(l+r)>>1;
			if(slope(q[mid],q[mid+1])<=s[i])
				l=mid+1;
			else r=mid;
		}
		Here:;
		f[i]=f[q[l]]+s[i]*e[i]-s[i]*e[q[l]]+t*e[n]-t*e[q[l]];

自我感觉这两种二分方法是一样的哇/kk,但是第一种为什么会出错呢T^T。

2021/5/15 15:39
加载中...