zoukankan      html  css  js  c++  java
  • 【简●解】[USACO] 照片Photo

    【题目大意】

    (1)~(N)的序列上有(M)个区间,使得这(M)个小区间每个覆盖了且仅覆盖了一个点,求最多点数,如果无解,输出(-1)

    【分析】

    刚开始做的时候我是懵的。。。不管三七二十一开始想差分约束系统,无奈没那么好的思维,没想出来。。。
    一翻题解,,(WOC!!!)这是什么神仙(DP?)真的是学到了。。。

    我们设(f[i])表示序列的第(i)位是一个点时,序列(1)~(i)的最多点数。

    那么(dp)方程就很好推了:设(j)<(i),即有(f[i]=max(f[j]+1, f[i]))

    现在我们需要解决的是(j)的范围,也就是(f[i])能从哪些状态中转移过来。

    我们想,如果第(i)位是一个点,那么所有包含这个点的区间都不能再有点,也就是说,(j)必须小于包含第(i)位这个点的区间中最小的左端点
    同样的,每个区间上必须有一个点,所以,(j)必须大于或等于不包含第(i)位这个点的区间中最大的左端点

    至于怎么求,大家可以(YY)了。

    我们会惊奇地发现(DP)方程满足单调性,于是单调队列走起。

    细节见代码。

    至于差分约束的做法嘛,,,以后会补的,,,咕咕咕

    【code】

    //#include<bits/stdc++.h>
    #pragma GCC optimize("O3")
    #pragma GCC optimize("O2")
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int MAX = 2000000 + 5;
    inline int read(){
    	int f = 1, x = 0;char ch;
    	do { ch = getchar(); if (ch == '-') f = -1; } while (ch < '0'||ch>'9');
    	do {x = x*10+ch-'0'; ch = getchar(); } while (ch >= '0' && ch <= '9'); 
    	return f*x;
    }
    int n, m, l[MAX], r[MAX], f[MAX], ans, q[MAX];
    int main(){
    //	freopen("aaa.in", "r", stdin); 
    //	freopen("aaa.out", "w", stdout); 
    	int n = read(), m = read();
    	for (int i = 1;i <= n + 1; ++i) r[i] = i - 1;
    	for (int i = 1;i <= m; ++i) {
    		int x = read(), y = read();
    		r[y] = min(r[y], x - 1);
    		l[y + 1] = max(l[y + 1], x);
    	}
    	for (int i = n; i > 0; --i) r[i] = min(r[i], r[i + 1]);
    	for (int i = 2; i < n + 2; ++i) l[i] = max(l[i], l[i - 1]);	
    	int j = 1, h = 1, t = 1; q[1] = 0;
    	for (int i = 1;i <= n + 1; ++i) {
    		while (j <= r[i] && j <= n) {
    			if (f[j] == -1) {
    				++j;
    				continue;
    			}
    			while (f[j] > f[q[t]] && h <= t) --t;
    			q[++t] = j;
    			++j;
    		}
    		while (q[h] < l[i] && h <= t) ++h;
    		if (h <= t) f[i] = f[q[h]] + (i != n+1 ? 1 : 0);
    		else f[i] = -1;
    	}
    	printf("%d", f[n + 1]);
    	return 0;
    }
    
  • 相关阅读:
    字符序列(characts)
    装载问题(load)
    哈密顿路
    犯罪团伙
    回溯算法
    维修机器人
    旅行计划
    皇后游戏
    运输
    亲身实测可用的java实现wordxlsxpdf文件下载功能
  • 原文地址:https://www.cnblogs.com/silentEAG/p/10804519.html
Copyright © 2011-2022 走看看