题解 P2466 【[SDOI2008]Sue的小球】
Bartholomew · · 题解
对一类动态规划问题的研究
(摘自)湖南省长沙市第一中学 徐源盛 论文 By Bartholomew
当前决策对未来“行动”的费用影响只与当前决策有关 好久没有写博客了,最近准备攻一波集训队论文(慌
引自论文: 在常规动态规划问题中,我们面临当前状态时“行动”造成的花费往往与这个 状 态 是 同 时 计 算 的 。 例 如 在 经 典 的 石 子 合 并 问 题 中 , 规 划 方 程 为
合并到一起这一“行动”的费用加进去。这很符合我们的思维习惯。 然而近年来频繁出现一类动态规划问题,在这类问题中,当前“行动”的费用 的一部分需要在之前决策时被计算并以状态的形式对当前状态造成影响。造成这 一独特的计算的原因就是当前的决策会对未来的“行动”费用造成影响。这类问题 构造方程往往比较困难,需要仔细分析原题,找到矛盾所在。
那么简单来说就是现在的决策内容会对之后的计算价值产生影响
那么我们怎么办:简单,如果这个影响是我们能够求的,那么我们就当前计算就好了!
题解
先把所有的点包括起点按
很容易想到用
用
即除了 i 到 j 这一段的彩蛋外的 所有彩蛋下落速度和,那么很容易得到方程:
答案就是
所以我们应该记住:对于当前决策影响未来的问题->就是现在算将来的影响再进行DP
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 1005
#define INF 0x3f3f3f3f
using namespace std;
int n, leftn, rightn;
double m, f[2][N][N], w[N][N], sum[N], getn;
struct node
{
double x, y, v;
} a[N];
inline bool cmp(node A, node B)
{
return A.x < B.x;
}
int main(int argc, char const *argv[])
{
scanf("%d%lf", &n, &m);
a[1] = node{m, 0.0, 0.0};
for(int i = 2; i <= n + 1; i++)
scanf("%lf", &a[i].x);
for(int i = 2; i <= n + 1; i++)
scanf("%lf", &a[i].y);
for(int i = 2; i <= n + 1; i++)
scanf("%lf", &a[i].v), getn += a[i].v;
sort(a + 1, a + 2 + n, cmp);
for(int i = 1; i <= n + 1; i++)
{
sum[i] = sum[i - 1] + a[i].v;
if(fabs(a[i].x - m) <= 1e-15 && fabs(a[i].y - 0.0) <= 1e-15)
{
leftn = rightn = i;
}
}
memset(f, -INF, sizeof f);
f[0][leftn][leftn] = f[1][rightn][rightn] = 0.00;
for(register int k = 1; k <= n + 1; ++k)
{
for(register int i = 1; i + k <= n + 1; ++i)
{
int j = i + k;
f[0][i][j] = a[i].y + max(f[0][i + 1][j] - (a[i + 1].x - a[i].x) * (sum[n + 1] + sum[i] - sum[j]),
f[1][i + 1][j] - (a[j].x - a[i].x) * (sum[n + 1] + sum[i] - sum[j]));
f[1][i][j] = a[j].y + max(f[1][i][j - 1] - (a[j].x - a[j - 1].x) * (sum[n + 1] + sum[i - 1] - sum[j - 1]) ,
f[0][i][j - 1] - (a[j].x - a[i].x) * (sum[n + 1] + sum[i - 1] - sum[j - 1]));
}
}
printf("%.3lf\n", max(f[1][1][n + 1], f[0][1][n + 1]) / 1000.0);
return 0;
}