1 条题解
-
1
首先每个球的初始高度不影响决策,真正有影响的在于其 值。
按横坐标排序,进行区间 dp。
设 表示考虑 的球,当前在左 / 右端点时对于答案已有的最小损失。特别的,我们把起点变为一个 的球。
损失包括内部的损失以及外部的损失。
这就是一种贡献提前计算的思想。
于是有 dp 方程(可能有些长):
$$f_{l,r,0}=\min\{f_{l+1,r,0}+(x_{l+1}-x_l)\times((\sum v)-(\sum_{i=l+1}^rv)),f_{l+1,r,1}+(x_r-x_l)\times((\sum v)-(\sum_{i=l+1}^rv))\} $$$$f_{l,r,1}=\min\{f_{l,r-1,1}+(x_r-x_{r-1})\times((\sum v)-(\sum_{i=l}^{r-1}v)),f_{l,r-1,0}+(x_r-x_l)\times((\sum v)-(\sum_{i=l}^{r-1}v))\} $$最后答案即 。
直接 dp 即可。
复杂度 。
#include <algorithm> #include <stdio.h> #include <vector> typedef long long llt; typedef unsigned uint;typedef unsigned long long ullt; typedef bool bol;typedef char chr;typedef void voi; typedef double dbl; template<typename T>bol _max(T&a,T b){return(a<b)?a=b,true:false;} template<typename T>bol _min(T&a,T b){return(b<a)?a=b,true:false;} template<typename T>T lowbit(T n){return n&-n;} template<typename T>T gcd(T a,T b){return b?gcd(b,a%b):a;} template<typename T>T lcm(T a,T b){return(a!=0||b!=0)?a/gcd(a,b)*b:(T)0;} template<typename T>T exgcd(T a,T b,T&x,T&y){if(b!=0){T ans=exgcd(b,a%b,y,x);y-=a/b*x;return ans;}else return y=0,x=1,a;} template<typename T>T power(T base,T index,T mod) { T ans=1%mod; while(index) { if(index&1)ans=ans*base%mod; base=base*base%mod,index>>=1; } return ans; } llt Dp[2][1005][1005]; struct point{llt x,v;uint id;}P[10005]; llt VSum[1005][1005]; int main() { #ifdef MYEE freopen("QAQ.in","r",stdin); // freopen("QAQ.out","w",stdout); #endif uint n;scanf("%u%lld",&n,&P[0].x);llt ans=0,g=0,w; for(uint i=1;i<=n;i++)scanf("%lld",&P[i].x),P[i].id=i; for(uint i=1;i<=n;i++)scanf("%lld",&w),ans+=w; for(uint i=1;i<=n;i++)scanf("%lld",&P[i].v),g+=P[i].v; std::sort(P,P+n+1,[](point a,point b){return a.x<b.x;}); for(uint i=0;i<=n;i++)VSum[i][i]=P[i].v,Dp[0][i][i]=Dp[1][i][i]=P[i].id?1e12:0; for(uint d=1;d<=n;d++)for(uint l=0;l+d<=n;l++) VSum[l][l+d]=VSum[l][l+d-1]+P[l+d].v, Dp[0][l][l+d]=std::min(Dp[0][l+1][l+d]+(P[l+1].x-P[l].x)*(g-VSum[l+1][l+d]), Dp[1][l+1][l+d]+(P[l+d].x-P[l].x)*(g-VSum[l+1][l+d])), Dp[1][l][l+d]=std::min(Dp[1][l][l+d-1]+(P[l+d].x-P[l+d-1].x)*(g-VSum[l][l+d-1]), Dp[0][l][l+d-1]+(P[l+d].x-P[l].x)*(g-VSum[l][l+d-1])); ans-=std::min(Dp[0][0][n],Dp[1][0][n]); printf("%.3lf\n",ans/1000.); return 0; }
- 1
信息
- ID
- 2037
- 时间
- 1000ms
- 内存
- 64MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 8
- 已通过
- 5
- 上传者