zoukankan      html  css  js  c++  java
  • bzoj 3379

    Description

    一个数轴上有 (n le 1000) 个位置, 每个位置有一个时间 (t_i)

    要求在 时刻 (t_i) 后, 至少经过该位置一次. (去交作业)

    求从 (0) 号点出发前往 (B) 号点, 满足上述条件的最小需要时间

    Solution 1

    CQzhangyu的做法. 非常的妙啊

    (ge t) 不好做, 走过的位置以后可能又会突然冒出一个人, 决策的顺序位置.

    考虑反着来, 先二分答案 (Ans), 并从 (B)(0) 走.

    这样限制条件变成了 (le Ans - t_i), 这样就之用在限制时间内经过一次该点即可

    直接使用区间dp, 复杂度 (O(n^2log n))

    Solution 2

    考虑初始状态 ([1, n]) 区间均未交作业

    接着你会进去区间内乱走一通, 交一些作业. 且此时你一直没有交边界的作业

    但是边界的作业迟早是要交的, 两个边界中, 必有一个是 先被到达的

    不妨设 ([a,b]) 先到达了 (a), 那么接下来, (b) 一定是要过去的, 中间的点都是必须被经过的.

    而这些中间被经过的, 若是在乱走到达 (a) 之前交了作业, 将其换至 到 (a) 后往 (b) 走的过程中再交是没有影响的.

    于是, 最优的决策, 一定是选择区间的一端 先交作业

    接着就可以使用区间dp, 区间从大往小走就好了

    Notice

    坐标有 (0)

    Code

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <cmath>
    #include <algorithm>
    #define rep(i, a, b) for (int i = (a), _ = (b); i <= _; ++ i)
    #define per(i, a, b) for (int i = (a), _ = (b); i >= _; -- i)
    #define For(i, a, b) for (int i = (a), _ = (b); i < _; ++ i)
    #define ri rd<int>
    using namespace std;
    const int N = 1007;
    const int INF = 1e9 + 7;
    
    template<class T> inline T rd() {
    	bool f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = 0;
    	T x = 0; for (; isdigit(c); c = getchar()) x = x * 10 + c - 48; return f ? x : -x;
    }
    
    int m, n, cur;
    int t[N];
    int f[N][N];
    int lf, rt;
    
    int main() {
    #ifndef ONLINE_JUDGE
    	freopen("a.in", "r", stdin);
    #endif
    
    	m = ri(), n = ri(), cur = ri() + 1;
    
    	lf = n + 1, rt = 0;
    	rep (i, 1, m) {
    		int x = ri() + 1, y = ri();
    		t[x] = max(t[x], y);
    		lf = min(lf, x), rt = max(rt, x);
    	}
    	
    	memset(f, 0x3f, sizeof f);
    	f[lf][rt] = max(lf - 1, t[lf]), f[rt][lf] = max(rt - 1, t[rt]);
    
    	per (l, rt-lf-1, 0) rep (i, lf, rt - l) {
    		int j = i + l;
    		f[i][j] = min(f[i][j], max(t[i], min(f[i-1][j] + 1,	f[j+1][i] + ((j + 1) - i))));
    		f[j][i] = min(f[j][i], max(t[j], min(f[i-1][j] + (j - (i - 1)), f[j+1][i] + 1)));
    	}
    	
    	int res = INF;
    	rep (i, lf, rt) res = min(res, f[i][i] + abs(i - cur));
    	printf("%d
    ", res);
    
    	return 0;
    }
    
  • 相关阅读:
    泛型中的类型擦除
    chatty: uid=10549(u0_a549) com.exampleidentical 40 lines
    Android 属性动画ObjectAnimator和ValueAnimator讲解
    解决Error:Unable to find method 'org.gradle.api.internal.project.ProjectInternal.
    Android Studio 模拟器无法打开 emulator: ERROR: x86 emulation currently requires hardware
    有关 java 不定参数
    数据处理
    有关SharedPreference的使用
    关于Fragment的onActivityResult 不执行
    Java GC回收机制
  • 原文地址:https://www.cnblogs.com/acha/p/7768347.html
Copyright © 2011-2022 走看看