BZOJ 2037 [Sdoi2008]Sue的小球

区间DP

费用提前计算。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
int dp[1005][1005][2];
int ps[1005],n,st,ans;
struct Egg{int x,y,v;}a[1005];
bool cmp(Egg a,Egg b)
{return a.x<b.x;}
int main()
{
    scanf("%d%d",&n,&st);
    F(i,1,n) scanf("%d",&a[i].x);
    F(i,1,n) scanf("%d",&a[i].y);
    F(i,1,n) scanf("%d",&a[i].v);
    sort(a+1,a+n+1,cmp);
    F(i,1,n) ans+=a[i].y; ps[0]=0;
    F(i,1,n) ps[i]=ps[i-1]+a[i].v;
    F(i,1,n)
    {
        dp[i][i][0]=dp[i][i][1]=a[i].y-abs(st-a[i].x)*ps[n];
    }
    F(len,2,n) F(i,1,n-len+1)
    {
         
        int j=i+len-1;if (j>n) break;
        dp[i][j][0]=max(dp[i+1][j][0]+a[i].y-abs(a[i].x-a[i+1].x)*(ps[i]+ps[n]-ps[j]),
                        dp[i+1][j][1]+a[i].y-abs(a[i].x-a[j].x)*(ps[i]+ps[n]-ps[j]));
        dp[i][j][1]=max(dp[i][j-1][1]+a[j].y-abs(a[j].x-a[j-1].x)*(ps[i-1]+ps[n]-ps[j-1]),
                        dp[i][j-1][0]+a[j].y-abs(a[j].x-a[i].x)*(ps[i-1]+ps[n]-ps[j-1]));
    }
    printf("%.3f\n",max(dp[1][n][0],dp[1][n][1])/1000.0);
    return 0;
}

  

posted @ 2017-03-19 21:13  SfailSth  阅读(158)  评论(0编辑  收藏  举报