P2466 [SDOI2008] Sue 的小球
/* XOY 一排点(xi,yi) 下降vi/s 从(x0,y0)出发 lft/rht pre:按坐标xi排序 假设已经走了i-j 在决定走新点 时 可以去 i-1/j+1 现在的pos==i/j 正着 很难算贡献 收益max->损失min ->dp[i][j]:从(x0,y0) 走了i-j 位置i 损失min -> f[i][j]:从(x0,y0) 走了i-j 位置j 损失min 考虑如何推 已经经过的时间会对对后面的 方程产生影响<---走过的点不会再走 --->已经经过的时间随时记录 posi->posj time+=(posj-posi)*未走过的总和 mem dp f -1 len:1-n i:1---n-len+1 j:i+len-1---n dp[i][j]=max(dp[i][j],dp[i+1][j]+(xi+1 -xi)*(sum(1,i)+sum(j+1,n)) */ /* 3 0 -4 -2 2 22 30 26 1 9 8 0.000 */ #include<cstdio> #include<iostream> #include<algorithm> #include<cmath> #include<string.h> #include<queue> #include<vector> #include<bits/stdc++.h> #define ll long long #define ddd printf("-----------------------\n"); using namespace std; const int maxn=1e3 +10; const int mod=998244353; const int inf=0x3f3f3f3f; struct node{ int x,y,v; }ball[maxn]; bool cmp(node a,node b){ return a.x<b.x; } int n,x0; int f[maxn][maxn],g[maxn][maxn],tot,pre[maxn]; int main() { ios::sync_with_stdio(false); memset(f,inf,sizeof(f)),memset(g,inf,sizeof(g)); cin>>n>>x0; for(int i=1;i<=n;i++) cin>>ball[i].x; for(int i=1;i<=n;i++) cin>>ball[i].y,tot+=ball[i].y; for(int i=1;i<=n;i++) cin>>ball[i].v; ball[++n]={x0,0,0}; sort(ball+1,ball+1+n,cmp); for(int i=1;i<=n;i++) pre[i]=pre[i-1]+ball[i].v; for(int i=1;i<=n;i++) if(ball[i].x==x0&&ball[i].y==0&&ball[i].v==0) f[i][i]=g[i][i]=0; for(int len=2;len<=n;len++) { for(int i=1,j=i+len-1;i<=n&&j<=n;i++,j=i+len-1) { //int j=i+len-1; f[i][j]=min(f[i][j],f[i+1][j]+(ball[i+1].x-ball[i].x)*(pre[i]+pre[n]-pre[j])); f[i][j]=min(f[i][j],g[i+1][j]+(ball[j].x-ball[i].x)*(pre[i]+pre[n]-pre[j])); g[i][j]=min(g[i][j],g[i][j-1]+(ball[j].x-ball[j-1].x)*(pre[n]-pre[j-1]+pre[i-1])); g[i][j]=min(g[i][j],f[i][j-1]+(ball[j].x-ball[i].x)*(pre[n]-pre[j-1]+pre[i-1])); } } printf("%.3lf\n",1.00*(tot-min(f[1][n],g[1][n]))/1000.00); return 0; }
#include<bits/stdc++.h> #define int long long using namespace std; const int N=1e3+10; int n,sx,w[N][N],sum1[N],sum2[N],f[N][N][2]; struct node { int x,y,v; friend bool operator < (const node &A,const node &B){return A.x<B.x;} }a[N]; signed main() { scanf("%lld%lld",&n,&sx); for(int i=1; i<=n; i++) scanf("%lld",&a[i].x); for(int i=1; i<=n; i++) scanf("%lld",&a[i].y); for(int i=1; i<=n; i++) scanf("%lld",&a[i].v); a[++n]={sx,0,0}; sort(a+1,a+1+n); for(int i=1; i<=n; i++) sum1[i]=sum1[i-1]+a[i].v; for(int i=n; i>=1; i--) sum2[i]=sum2[i+1]+a[i].v; int x; for(int i=1; i<=n; i++) { for(int j=i; j<=n; j++) w[i][j]=sum1[i-1]+sum2[j+1]; if(a[i].x==sx && a[i].y==0 && a[i].v==0) x=i; } memset(f,~0x7f,sizeof(f)); f[x][x][0]=f[x][x][1]=0; for(int len=2; len<=n; len++) { for(int i=1; i+len-1<=n; i++) { int j=i+len-1; f[i][j][0]=max(f[i+1][j][0]-w[i+1][j]*(a[i+1].x-a[i].x),f[i+1][j][1]-w[i+1][j]*(a[j].x-a[i].x))+a[i].y; f[i][j][1]=max(f[i][j-1][1]-w[i][j-1]*(a[j].x-a[j-1].x),f[i][j-1][0]-w[i][j-1]*(a[j].x-a[i].x))+a[j].y; // cout<<i<<" "<<j<<" "<<a[i].y<<" "<<max(f[i][j][0],f[i][j][1])<<endl; } } printf("%.3lf\n",1.0000*max(f[1][n][0],f[1][n][1])/1000.0000); return 0; } /* 1 0 0 5 5 */

浙公网安备 33010602011771号