O(n) 斜率优化玄1关求条
查看原帖
O(n) 斜率优化玄1关求条
865625
KobeBeanBryantCox楼主2025/7/25 16:40

rt,解决问题了才关注

按照这个题解思路来的

目前 WA 90 pts

// O(n) 做法
#include<bits/stdc++.h>
#define Code using
#define by namespace
#define wjb std
Code by wjb;
int in()
{
	int k=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9')k=k*10+c-'0',c=getchar();
	return k*f;
}
void out(int x)
{
	if(x<0)putchar('-'),x=-x;
	if(x<10)putchar(x+'0');
	else out(x/10),putchar(x%10+'0');
}
const int N=60;
struct node{int x,y;};
long double calc(node &a,node &b){return (long double)(a.y-b.y)/(a.x-b.x);}
struct slope
{
	node q[N];int l,r;
	slope(){l=1,r=0;}
	void insert(int x,int y)
	{
		node t={x,y};
		while(l<r&&calc(q[r],q[r-1])>calc(q[r],t))r--;
		q[++r]=t;
	}
	int ask(int k)
	{
		while(l<r&&k>calc(q[l],q[l+1]))l++;
		return q[l].y-k*q[l].x;
	}
}L,R;
int w[N],s[N],p[N],dis[N],dp[N],ans=0;
int main()
{
	int n=in(),c=in();
	for(int i=1;i<=n;i++)p[i]=in(),w[i]=in();
	for(int i=1;i<=n;i++)
	{
		dis[i]=abs(p[i]-p[c]);
		s[i]=s[i-1]+w[i];
		ans+=dis[i]*w[i];
	}
	int l=c,r=c;
	L.insert(2*s[r],0),R.insert(-2*s[l-1],0);
	while(l>1&&r<n)
	{
		int t1=L.ask(dis[l-1])+2*dis[l-1]*(s[l-2]+s[n]);
		int t2=R.ask(dis[r+1])+2*dis[r+1]*(s[n]-s[r+1]);
		if(t1<t2)dp[--l]=t1,R.insert(-2*s[l-1],dp[l]);
		else dp[++r]=t2,L.insert(2*s[r],dp[r]);
	}
	if(l==1)ans+=dp[1];
	else ans+=dp[n];
	out(ans);
	return 0;
}

附上错误数据:

input:

20 18
3 100
4 20
6 50
7 60
8 10
9 100
10 20
12 20
15 20
17 100
18 80
20 100
24 10
25 60
26 70
31 30
33 10
38 10
40 100
47 10

answer:

24370

output:

35670
2025/7/25 16:40
加载中...