BZOJ 2037 Sue的小球 发表于 2017-01-17 | 更新于 2018-06-17 LinkSolution将最大收益转化成最小损失,在转移的时候将损失提前计算,这样DP即可。 Code123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657//Code by Lucida#include<bits/stdc++.h>#define get(x) scanf("%d",&x)//#define debug(x) std::cout<<#x<<'='<<x<<std::endltemplate <class T> inline bool chkmx(T &a,const T &b){return a<b?a=b,1:0;}template <class T> inline bool chkmn(T &a,const T &b){return a>b?a=b,1:0;}typedef long long LL;const int MAXN=1000+11;const LL INF=1e15;using std::sort;using std::min;template <class T> inline T min(const T &a,const T &b,const T &c,const T &d){return min(min(a,b),min(c,d));}struct poi{int x,y,v;}p[MAXN];bool operator <(const poi &a,const poi &b){return a.x<b.x;}int sumv[MAXN],mid,n;LL f[MAXN][MAXN][2];bool ud[MAXN][MAXN][2];LL dist(int l,int r){return p[r].x-p[l].x;}LL sigmaV(int l,int r){return sumv[r]-sumv[l-1];}LL DP(int l,int r,int d){ if(r<mid || l>mid) return INF; if(ud[l][r][d]) return f[l][r][d]; LL &res=f[l][r][d];ud[l][r][d]=1; if(d==0) res=min(DP(l+1,r,0)+(sigmaV(1,l)+sigmaV(r+1,n))*dist(l,l+1), DP(l+1,r,1)+(sigmaV(1,l)+sigmaV(r+1,n))*dist(l,r)); else res=min(DP(l,r-1,1)+(sigmaV(1,l-1)+sigmaV(r,n))*dist(r-1,r), DP(l,r-1,0)+(sigmaV(1,l-1)+sigmaV(r,n))*dist(l,r)); return res;}int main(){ int x0,sumy=0;get(n),get(x0); for(int i=1;i<=n;i++) get(p[i].x); for(int i=1;i<=n;i++) get(p[i].y); for(int i=1;i<=n;i++) get(p[i].v); p[++n].x=x0;p[n].y=0;p[n].v=0; sort(p+1,p+1+n); for(int i=1;i<=n;i++) { sumv[i]=sumv[i-1]+p[i].v; sumy+=p[i].y; if(p[i].x==x0 && p[i].y==0) { f[i][i][0]=f[i][i][1]=0; ud[i][i][0]=ud[i][i][1]=1; mid=i; } } printf("%.3lf\n",(sumy-min(DP(1,n,0),DP(1,n,1)))/1000.0); return 0;}/* AC Record(Bugs) * * * * * * * * * * * */