2037: [Sdoi2008]Sue的小球

2037: [Sdoi2008]Sue的小球

链接

 

题解

  论文

 

代码

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<cctype>
 7 
 8 using namespace std;
 9 
10 const int N = 1010;
11 
12 struct Node{
13     int x,y,v;
14     bool operator < (const Node &a) const {
15         return x < a.x;
16     }
17 }d[N];
18 int dp[N][N][2],sum[N];
19 
20 inline int read() {
21     int x = 0,f = 1;char ch=getchar();
22     for (; !isdigit(ch); ch=getchar()) if(ch=='-')f=-1;
23     for (; isdigit(ch); ch=getchar()) x=x*10+ch-'0';
24     return x*f;
25 }
26 
27 int main() {
28     int n = read(), x0 = read();
29     for (int i=1; i<=n; ++i) d[i].x = read();
30     for (int i=1; i<=n; ++i) d[i].y = read();
31     for (int i=1; i<=n; ++i) d[i].v = read();
32     
33     sort(d+1,d+n+1);
34     for (int i=1; i<=n; ++i) sum[i] = sum[i-1] + d[i].v; // 对下降速度求前缀和 
35     
36     for (int i=1; i<=n; ++i) 
37         dp[i][i][0] = dp[i][i][1] = d[i].y - abs(x0-d[i].x)*sum[n]; //表示已经收集了[i,i]这个区间 
38         
39     for (int k=2; k<=n; ++k) {
40         for (int i=1; i+k-1<=n; ++i) { 
41             int j = i + k - 1;
42             dp[i][j][0] = max(dp[i+1][j][0] + d[i].y - (sum[n] - sum[j] + sum[i]) * (d[i+1].x - d[i].x),
43                               dp[i+1][j][1] + d[i].y - (sum[n] - sum[j] + sum[i]) * (d[j].x - d[i].x));
44             dp[i][j][1] = max(dp[i][j-1][0] + d[j].y - (sum[n] - sum[j-1] + sum[i-1]) * (d[j].x - d[i].x),
45                               dp[i][j-1][1] + d[j].y - (sum[n] - sum[j-1] + sum[i-1]) * (d[j].x - d[j-1].x));
46         }
47     }
48     
49     double ans = 1.0*(max(dp[1][n][0],dp[1][n][1]))/1000.0;
50     printf("%.3lf",ans);
51 
52     return 0;
53 }

 

posted @ 2018-06-09 21:03  MJT12044  阅读(182)  评论(0编辑  收藏  举报