您的位置:首页 > 产品设计 > UI/UE

bzoj 2037: [Sdoi2008]Sue的小球

2016-03-18 22:40 447 查看
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
struct data
{
int x,y,v;
}a[1009];
int f[1009][1009][2],n,x0,b[1009],sum[1009],tot;
bool cmp(data a1,data a2)
{
return a1.x<a2.x;
}
int main()
{
scanf("%d%d",&n,&x0);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i].x);
a[i].x-=x0;
}
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i].y);
tot+=a[i].y;
}
for(int i=1;i<=n;i++)
scanf("%d",&a[i].v);
sort(a,a+n+1,cmp);
for(int i=0;i<=n;i++)
b[i]=a[i].x;
x0=lower_bound(b,b+n+1,0)-b;
for(int i=x0-1;i>=0;i--)
sum[i]=sum[i+1]+a[i].v;
for(int i=x0+1;i<=n;i++)
sum[i]=sum[i-1]+a[i].v;
for(int i=x0+1;i<=n;i++)
{
f[x0][i][1]=f[x0][i-1][1]+(sum
+sum[0]-sum[i-1])*abs(a[i].x-a[i-1].x);
f[x0][i][0]=f[x0][i][1]+(sum
+sum[0]-sum[i])*abs(a[i].x);
}
for(int i=x0-1;i>=0;i--)
{
f[i][x0][0]=f[i+1][x0][0]+(sum
+sum[0]-sum[i+1])*abs(a[i].x-a[i+1].x);
f[i][x0][1]=f[i][x0][0]+(sum
+sum[0]-sum[i])*abs(a[i].x);
}
for(int i=x0-1;i>=0;i--)
for(int j=x0+1;j<=n;j++)
{
f[i][j][0]=f[i+1][j][0]+(sum[0]-sum[i+1]+sum
-sum[j])*abs(a[i].x-a[i+1].x);
f[i][j][0]=min(f[i][j][0],f[i+1][j][1]+(sum[0]-sum[i+1]+sum
-sum[j])*abs(a[i].x-a[j].x));
f[i][j][1]=f[i][j-1][1]+(sum[0]-sum[i]+sum
-sum[j-1])*abs(a[j].x-a[j-1].x);
f[i][j][1]=min(f[i][j][1],f[i][j-1][0]+(sum[0]-sum[i]+sum
-sum[j-1])*abs(a[j].x-a[i].x));
}
int x0=min(f[0]
[1],f[0]
[0]);
printf("%.3lf\n",(tot-x0)*0.001);
return 0;
}


很像以前在codevs上做的关路灯那个题,区间型DP,可知他不可能越过一盏灯去关另一盏。所以从起点开始,依次向两边扩展,f[i][j][0]表示关完区间[i,j]停在左边,[1]表示停在右边。

f[i][j][0]即可从f[i+1][j][0]转移来,又可从f[i+1][j][1]转移来。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: