萌新刚学斜率优化须臾,求查错
查看原帖
萌新刚学斜率优化须臾,求查错
94726
萧道成楼主2021/8/20 11:50

~```

#include<bits/stdc++.h>
#define ll long long
#define  N 100001
#define INF 0x3f3f3f3f
using namespace std;
ll f[N],q[N],sum[N],cnt[N],t[N],s[N],n,m,maxn=0,anst=INF;
//设最后出发的时间是i 
//sum(i)为i前面人的t和,cnt为这些人数
//方程f(i)=min(f(j)+(cnt(i)-cnt(j))*i-(sum(i)-sum(j)))
//特殊的j<=i-m 
//展开f(i)-i*cnt(i)+sum(i)【+i*cnt(j)】=f(j)+sum(j)
//于是y=f(j)+sum(j),x=cnt(j),k=i,b=f(i)-i*cnt(i)+sum(i)
inline double xt(ll i)
{
	return cnt[i];
}
inline double yt(ll i)
{
	return f[i]+sum[i];
}
inline double kt(ll i,ll j)
{
	if(xt(i)==xt(j)) 
	return 1.0*(yt(i)-yt(j))/(1e-9);
	return (yt(i)-yt(j))/(xt(i)-xt(j));
}
int main()
{
	cin>>n>>m;
	for(ll i=1;i<=n;i++)
	{
		cin>>t[i];
		sum[t[i]]+=t[i];
		cnt[t[i]]++;
		maxn=max(t[i],maxn);
	}
	for(ll i=1;i<maxn+m;i++)
	{
		sum[i]+=sum[i-1];
		cnt[i]+=cnt[i-1];
	}
	ll head=1;
	ll tail=0;
	for(ll i=0;i<maxn+m;i++)
	{
	    if(i>=m)
		while(head<tail&&kt(q[tail-1],q[tail])>=kt(q[tail],i-m))
		tail--;
		if(i>=m)
		q[++tail]=i-m;
		
		//f[i]=i*cnt[i]-sum[i];
		while(head<tail&&kt(q[head],q[head+1])<=i)
		head++;
		ll j=q[head];
		f[i]=cnt[i]*i-sum[i];
		
		
		if(head<=tail)
		f[i]=min(f[i],f[j]+(cnt[i]-cnt[j])*i-sum[i]+sum[j]);
		
		
		
	}
	for(ll i=maxn;i<maxn+m;i++)
	anst=min(anst,f[i]);
	cout<<anst;
	return 0;
}
2021/8/20 11:50
加载中...