• 洛谷P2466 [SDOI2008]Sue的小球 题解 区间DP+费用提前计算


    题目链接:https://www.luogu.com.cn/problem/P2466

    题目大意:略。

    解题思路:

    首先将 (n) 个彩蛋按照 (x) 从小到大排序。

    然后定义状态 (f[L][R][s]),其含义为:

    • (s=0) 时:接完了第 ([L,R]) 范围内的所有彩蛋,且当前处在最左边的位置((L)处),收获的得分+给未来造成的得分的损耗之和的最大值;
    • (s=1) 时:接完了第 ([L,R]) 范围内的所有彩蛋,且当前处在最右边的位置((R)处),收获的得分+给未来造成的得分的损耗之和的最大值。

    则状态转移方程为:

    (L = R) 时,

    [f[L][R][s] = y_L - |x_0 - x_L| imes sum_{1 le i le n} v_i ]

    (L lt R) 时,

    [f[L][R][0] = max{f[L+1][R][0] + y_L - (sum_{ile L} v_i + sum_{i gt R} v_i) imes (x_{L+1} - x_L), f[L+1][R][1] + y_L - (sum_{ile L} v_i + sum_{i gt R} v_i) imes (x_R - x_L) } ]

    [f[L][R][1] = max {f[L][R-1][0] + y_R - (sum_{i lt L} v_i + sum_{i ge R} v_i) imes (x_R - x_L) , f[L][R-1][1] + y_R - (sum_{i lt L} v_i + sum_{i ge R} v_i) imes (x_R - x_{R-1}) } ]

    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1010;
    struct Node {
        int x, y, v;
        Node() {};
        Node(int _x, int _y, int _v) { x = _x; y = _y; v = _v; }
    } a[maxn];
    bool cmp(Node a, Node b) {
        return a.x < b.x;
    }
    int n, x0;
    long long f[maxn][maxn][2], sumv[maxn];
    bool vis[maxn][maxn][2];
    long long dfs(int L, int R, int s) {
        if (L == R) {
            return a[L].y - abs(x0 - a[L].x) * sumv[n];
        }
        if (vis[L][R][s]) return f[L][R][s];
        vis[L][R][s] = true;
        if (s == 0) {
            long long tmp1 = dfs(L+1, R, 0) + a[L].y - (sumv[L] + sumv[n] - sumv[R]) * (a[L+1].x - a[L].x);
            long long tmp2 = dfs(L+1, R, 1) + a[L].y - (sumv[L] + sumv[n] - sumv[R]) * (a[R].x - a[L].x);
            return f[L][R][0] = max(tmp1, tmp2);
        }
        else {  // s == 1
            long long tmp1 = dfs(L, R-1, 0) + a[R].y - (sumv[L-1] + sumv[n] - sumv[R-1]) * (a[R].x - a[L].x);
            long long tmp2 = dfs(L, R-1, 1) + a[R].y - (sumv[L-1] + sumv[n] - sumv[R-1]) * (a[R].x - a[R-1].x);
            return f[L][R][1] = max(tmp1, tmp2);
        }
    }
    int main() {
        scanf("%d%d", &n, &x0);
        for (int i = 1; i <= n; i ++) scanf("%d", &a[i].x);
        for (int i = 1; i <= n; i ++) scanf("%d", &a[i].y);
        for (int i = 1; i <= n; i ++) scanf("%d", &a[i].v);
        sort(a+1, a+1+n, cmp);
        for (int i = 1; i <= n; i ++) sumv[i] = sumv[i-1] + a[i].v;
        printf("%.3lf
    ", (double) max(dfs(1, n, 0), dfs(1, n, 1))/ 1000.0);
        return 0;
    }
    
  • 相关阅读:
    ID控制tab切换
    jQuery控制图片的hover效果
    popup效果
    第一篇博客
    Java面试中hashCode()与equals(Object obj)方法关系的准确回答
    小福bbs凡事预则立
    编译cppunit
    EasyUI Datagrid数据网格
    发送邮件
    京东笔试
  • 原文地址:https://www.cnblogs.com/quanjun/p/13603864.html
Copyright © 2020-2023  润新知