求助啊啊啊啊~~~
查看原帖
求助啊啊啊啊~~~
290959
聊机楼主2021/6/9 22:24

由于蒟蒻初学斜率优化DP,所以用了三天三夜时间才推出了DP方程,本来想迅速水过,谁知一提交只有11分……

先说一下我的方程: f[i]=min0j<i(sum[i]sum[j]+f[j](d[i]d[j])×p[j](c[i1]c[j])f[i]=\min_{0\le j<i} (sum[i]-sum[j]+f[j]-(d[i]-d[j])\times p[j]-(c[i-1]-c[j])

sum是前i个里面把所有的产品运到i所需要的值加上前i个的c的和。

这个正确性应该是可以保证的,我有66分提交记录为证

然后就是斜率优化,我把式子这样转化了一下: (d[i]d[j])×p[j]sum[i]+f[i]+c[i1]=f[j]+c[j]sum[j](d[i]-d[j])\times p[j]-sum[i]+f[i]+c[i-1]=f[j]+c[j]-sum[j]

然后以p[j]为横坐标,f[j]+c[j]-sum[j]为纵坐标,d[i]-d[j]为斜率,sum[i]+f[i]+c[i-1]为截距进行斜率优化,因为d[i]是单调的,所以我用的是单调队列。

然后不知道为啥就WA了。 代码↓

#include<bits/stdc++.h>
using namespace std;
inline int read(){
	int k=0;bool f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')f=0;ch=getchar();}
	while(isdigit(ch)){k=(k<<1)+(k<<3)+(ch^48);ch=getchar();}
	return f?k:~k+1;
}
typedef long long ll;
const int N=1e6+2;
int n,q[N],l,r;
ll sum[N],d[N],p[N],c[N],f[N];
inline ll Y(int j){return f[j]+c[j]-sum[j];}
inline double slope(int i,int j){//这里我本来是直接用的斜率,后来怕精度问题,就改成相乘了,结果都是WA后9个点
	return (Y(j)-Y(i))*1.0/(p[j]-p[i]);
}
int main(){
	n=read();
	for(int i=1;i<=n;i++)
		d[i]=read(),
		p[i]=p[i-1]+read(),
		c[i]=c[i-1]+read(),
		sum[i]=sum[i-1]+p[i-1]*(d[i]-d[i-1])+c[i]-c[i-1];
    l=r=1;
    for(int i=1;i<=n;i++)
    {
    	while(l<r&&Y(q[l+1])-Y(q[l])<(d[i]-d[q[l]])*(p[q[l+1]]-q[l]))++l;
    	f[i]=sum[i]-sum[q[l]]+f[q[l]]-(d[i]-d[q[l]])*p[q[l]]-c[i-1]+c[q[l]];
    	while(l<r&&(Y(q[r])-Y(q[r-1]))*(p[i]-p[q[r]])>(Y(i)-Y(q[r]))*(p[q[r]]-p[q[r-1]]))--r;q[++r]=i;
	}
	printf("%lld",f[n]);
	return 0;
}

大犇们,救救孩子吧!!!

2021/6/9 22:24
加载中...