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 }