zoukankan      html  css  js  c++  java
  • 题解 P3842 【[TJOI2007]线段】

    大家写的都是普通的dp

    我来写一发滚动dp

    何为滚动dp?

    就是在转移的时候不断利用无用的空间,来避免 (MLE) 虽然这里没有必要

    (f[i][0]) 表示走完第i行且停在第i行的左端点最少用的步数

    (f[i][1]) 表示走完第i行且停在第i行的右端点最少用的步数

    那么递推方程很好推:

    f[i][0] = min(f[i-1][0] + abs(l[i-1] - r[i]), f[i-1][1] + abs(r[i-1] - r[i])) + r[i] - l[i] + 1,
    f[i][1] = min(f[i-1][0] + abs(l[i-1] - l[i]), f[i-1][1] + abs(r[i-1] - l[i])) + r[i] - l[i] + 1;
    

    这时候你可以发现,当前的状态只与 (f[i - 1][0/1]) 有关。

    所以可以得到以下代码 :

    f[i % 2][1] = min(f[i % 2 ^ 1][0] + abs(L[i % 2] - L[i % 2 ^ 1]), f[i % 2 ^ 1][1] + abs(R[i % 2 ^ 1] - L[i % 2])) + 1 + R[i % 2] - L[i % 2];
    f[i % 2][0] = min(f[i % 2 ^ 1][0] + abs(R[i % 2] - L[i % 2 ^ 1]), f[i % 2 ^ 1][1] + abs(R[i % 2 ^ 1] - R[i % 2])) + 1 + R[i % 2] - L[i % 2];
    

    完整代码:

    #include <algorithm>
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <cmath>
    #define N 5010
    #define M 1000010
    #define ls x << 1
    #define rs x << 1 | 1
    #define inf 0x3f3f3f3f
    #define inc(i) (++ (i))
    #define dec(i) (-- (i))
    #define mid ((l + r) >> 1)
     #define int long long
    //#define ll long long
    #define XRZ 19260817
    #define pai acos(-1)
    #define debug() puts("XRZ TXDY");
    #define mem(i, x) memset(i, x, sizeof(i));
    #define Next(i, u) for(register int i = head[u]; i ; i = e[i].nxt)
    #define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout);
    #define Rep(i, a, b) for(register int i = (a) , i##Limit = (b) ; i <= i##Limit ; inc(i))
    #define Dep(i, a, b) for(register int i = (a) , i##Limit = (b) ; i >= i##Limit ; dec(i))
    using namespace std;
    inline int read() {
        register int x = 0, f = 1; register char c = getchar();
        while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9') x = x * 10 + c 	- 48, c = getchar(); 
        return x * f;
    }
    inline int read_plus() {
        register int res = 0, ch = getchar();
        while(!isdigit(ch) and ch != EOF) ch = getchar();
        while(isdigit(ch)) res = ((res << 3) + (res << 1) + (ch - '0')) % XRZ, ch = getchar();
        return res;
    }
    int dx[10] = {0, 1, 1, 2, 2, -1, -1, -2, -2};
    int dy[10] = {0, 2, -2, 1, -1, 2, -2, 1, -1};
    int exgcd(int a, int b, int &x, int &y) {
    	if(b == 0) { x = 1, y = 0; return a;}
    	int now = exgcd(b, a % b, x, y);
    	int yy = x; x = y, y = yy - a / b * y;
    	return now;
    }
    int n, L[2], R[2], f[2][2];
    signed main() { n = read(), L[1] = read(), R[1] = read(), f[1][0] = R[1] * 2 - L[1] - 1, f[1][1] = R[1] - 1;
    	Rep(i, 2, n) { L[i % 2] = read(), R[i % 2] = read();
    		f[i % 2][1] = min(f[i % 2 ^ 1][0] + abs(L[i % 2] - L[i % 2 ^ 1]), f[i % 2 ^ 1][1] + abs(R[i % 2 ^ 1] - L[i % 2])) + 1 + R[i % 2] - L[i % 2];
    		f[i % 2][0] = min(f[i % 2 ^ 1][0] + abs(R[i % 2] - L[i % 2 ^ 1]), f[i % 2 ^ 1][1] + abs(R[i % 2 ^ 1] - R[i % 2])) + 1 + R[i % 2] - L[i % 2];
    //		printf("1 : %d %d
    ", f[i % 2][0], f[i % 2][1]); 
    	} printf("%d", min(f[n % 2][0] + n - L[n % 2], f[n % 2][1] + n - R[n % 2]));
    	return 0;
    }
    
  • 相关阅读:
    CF1515G
    杂题
    ARC120E
    CF1528F
    ICPC2021银川C
    gym102129F
    杂记6.15
    杂记5.12
    杂记4.1
    杂记3.17
  • 原文地址:https://www.cnblogs.com/Flash-plus/p/13834252.html
Copyright © 2011-2022 走看看