zoukankan      html  css  js  c++  java
  • codeforces 704B

    题目链接:http://codeforces.com/problemset/problem/704/B

    --------------------------------------------------------------------------------

    比赛时最远也就猜到了拆公式,算贡献这一步 然后就$GG$了

    结束后问了$Randolph87$ 他给了一个"括号匹配"的思路

    感觉这个思路比官方题解更可做 然后我就按照这个思路开始思考

    对于非起点非终点外的所有点 有这四种情况

    左入左出 左入右出 右入左出 右入右出

    每当加入一个新的点

    如果它是右入右出则当前区间的入度 $+1$ 出度 $+1$

    如果是左入左出则当前区间的入度 $-1$ 出度 $-1$

    另外两种情况则是入度出度都不改变

    (此处度数是对于整个区间讲的 或者说这个区间对应的有向图还需要增加$x$个入度和$y$个出度才能构成一个环)

    假设题目不限定起点终点 只要求一个回路 那么对于所有的点都这样做

    并且保证中间状态中入度出度都为正数 最终状态入度出度都为$0$即可

    然而题目是有起点和终点限制的一条路径

    因此我们可以强行连一条从终点出从起点入的代价为$0$的边

    .

    .

    .

    按照这个思路做下去 一部分人会$WA5$

    原因是在实现的时候 有可能只是限定了终点有一条方向向着起点的边

    于是中间还可能混入其他的点 并没有保证终点和起点的直接连接

    为了满足这个要求 我们可以在扫描到起点和终点之间的点的时候

    强行使得 入度$-1(s < e$时$)$ / 出度 $-1(s > e$时$)$

    这样就可以把这一部分完美地解决了

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    const int N = 5010;
    long long f[N][N];
    bool valid[N][N];
    int x[N], a[N], b[N], c[N], d[N];
    int n, s, e;
    void update(long long &x, long long y, bool &z)
    {
        if(!z)
        {
            z = 1;
            x = y;
            return;
        }
        x = min(x, y);
    }
    int main()
    {
        scanf("%d%d%d", &n, &s, &e);
        for(int i = 1; i <= n; ++i)
            scanf("%d", &x[i]);
        for(int i = 1; i <= n; ++i)
            scanf("%d", &a[i]);
        for(int i = 1; i <= n; ++i)
            scanf("%d", &b[i]);
        for(int i = 1; i <= n; ++i)
            scanf("%d", &c[i]);
        for(int i = 1; i <= n; ++i)
            scanf("%d", &d[i]);
        valid[0][0] = 1;
        int delta = 0;
        for(int i = 1; i <= n; ++i)
        {
            if(i == min(s, e))
                delta = s < e ? 1 : -1;
            else if(i == max(s, e))
                delta = 0;
            if(i != s && i != e)
                for(int j = 0; j <= i && j <= n - i; ++j)
                {
                    if(j && valid[i - 1][j - 1])
                        update(f[i][j], f[i - 1][j - 1] + b[i] + d[i] - x[i] * 2, valid[i][j]);
                    if((j || i == n) && valid[i - 1][j + 1])
                        update(f[i][j], f[i - 1][j + 1] + a[i] + c[i] + x[i] * 2, valid[i][j]);
                    if(j && valid[i - 1][j])
                    {
                        if(j > 1 || !delta)
                            update(f[i][j], f[i - 1][j] + min(a[i] + d[i], b[i] + c[i]), valid[i][j]);
                        else if(delta == 1)
                            update(f[i][j], f[i - 1][j] + a[i] + d[i], valid[i][j]);
                        else
                            update(f[i][j], f[i - 1][j] + b[i] + c[i], valid[i][j]);
                    }
                }
            else if(i == s)
                for(int j = 0; j <= i && j <= n - i; ++j)
                {
                    if(s < e && j && valid[i - 1][j - 1])
                        update(f[i][j], f[i - 1][j - 1] + d[i] - x[i], valid[i][j]);
                    if(s < e && j && valid[i - 1][j])
                        update(f[i][j], f[i - 1][j] + c[i] + x[i], valid[i][j]);
                    if(s > e && (j || i == n) && valid[i - 1][j + 1])
                        update(f[i][j], f[i - 1][j + 1] + c[i] + x[i], valid[i][j]);
                    if(s > e && j && valid[i - 1][j])
                        update(f[i][j], f[i - 1][j] + d[i] - x[i], valid[i][j]);
                }
            else
                for(int j = 0; j <= i && j <= n - i; ++j)
                {
                    if(s < e && (j || i == n) && valid[i - 1][j + 1])
                        update(f[i][j], f[i - 1][j + 1] + a[i] + x[i], valid[i][j]);
                    if(s < e && j && valid[i - 1][j])
                        update(f[i][j], f[i - 1][j] + b[i] - x[i], valid[i][j]);
                    if(s > e && j && valid[i - 1][j - 1])
                        update(f[i][j], f[i - 1][j - 1] + b[i] - x[i], valid[i][j]);
                    if(s > e && j && valid[i - 1][j])
                        update(f[i][j], f[i - 1][j] + a[i] + x[i], valid[i][j]);
                }
        }
        printf("%lld
    ", f[n][0]);
        return 0;
    }
  • 相关阅读:
    JS基础_函数的简介
    frp 使用入门
    树莓派开启smb
    python 反射调用
    VIDEOIO ERROR: V4L: can't open camera by index 0 for raspberryPi
    face_recognition 人脸识别报错
    安装FFMpeg CentOS 7
    Centos 7 smb 安装使用
    ImportError: libQtTest.so.4: cannot open shared
    Raspberry Pi 3b+ 配置摄像头
  • 原文地址:https://www.cnblogs.com/sagitta/p/5749312.html
Copyright © 2011-2022 走看看