POJ 3263-Tallest Cow

POJ 3263-Tallest Cow


Describe

FJ's N (1 ≤ N ≤ 10,000) cows conveniently indexed 1..N are standing in a line. Each cow has a positive integer height (which is a bit of secret). You are told only the height H (1 ≤ H ≤ 1,000,000) of the tallest cow along with the index I of that cow.

FJ has made a list of R (0 ≤ R ≤ 10,000) lines of the form "cow 17 sees cow 34". This means that cow 34 is at least as tall as cow 17, and that every cow between 17 and 34 has a height that is strictly smaller than that of cow 17.

For each cow from 1..N, determine its maximum possible height, such that all of the information given is still correct. It is guaranteed that it is possible to satisfy all the constraints.

Input

Line 1: Four space-separated integers: N, I, H and R
Lines 2..R+1: Two distinct space-separated integers A and B (1 ≤ A, BN), indicating that cow A can see cow B.

Output

Lines 1..N: Line i contains the maximum possible height of cow i.

Sample Input

9 3 5 5
1 3
5 3
4 3
3 7
9 8

Sample Output

5
4
5
3
4
4
5
5
5

Translation

给出n头牛的身高,和m对关系(a[i]能看见b[i]。即他们中间的牛都比他们矮,且a[ i ] <= b[ i ]。已知最高的牛为第p头,身高为h。求每头牛的身高最大可能是多少。

Solution

首先整体说一下做法:

n 头奶牛初始化为 H ,

对于每个限制,区间内如果有一头奶牛高度太高超限,则整个区间中各个元素 -1 ;continue;

最后输出得到的每个奶牛高度.

具体说一下:

有点偏贪心,首先将所有奶牛初始化为H,也就是最大值(我们可以假设一开始没有限制,这就是最优解).对于每次的两只奶牛x 和 y,我们只需将x 和 y之间的奶牛处理好就可以,如果中间有一只奶牛 i 的高度 (a_i) >= (a_x),那么我们要将这个区间[ x+1, y-1 ]所有的奶牛都 -1,为什么是整个区间而不是这一个第 i 头呢?

有一个条件不知道大家有木有发现,所有的限制的区间不会交叉,就是说不会出现比如3 看到 8, 5 看到 9,因为这是互相矛盾的,8左侧的点(包括3的右边,8的左边)严格小于8,所以5不可能越过8看到9.如此来看,这些区间就有了一些规律可循.(当然题目保证数据合法)

如果对于每次输入的区间处理中,我们在其中发现了一个超限的点,我们如果只修改它,那么这个区间内的原始相互关系可能被打破,如果题目中有这个区间内部的一个区间的限制的话就会错,所以我们把这一整个区间都 -1 以维持内部的相互关系,而减的是1又保证了最优性,此题得解.

!!我又想到了一种更好的解释方法,这样处理可以满足当前的及以前的限制。这样处理完一遍后,就可以满足题中所有限制且最优了。

Code

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn=10000+5;
int a[maxn],n,r;
int main(){
//	freopen("1.in","r",stdin);
	int x,y,p;
	scanf("%d%d%d%d",&n,&x,&y,&r);
	for(int i=1;i<=n;++i)a[i]=y;
	for(int i=1;i<=r;++i){
		scanf("%d%d",&x,&y);p=x;
		if(x>y)swap(x,y);
		for(int i=x+1;i<=y-1;++i)
			if(a[i]>=a[p]){
				for(int i=x+1;i<=y-1;++i)
					a[i]--;
				break;
			}
	}
	for(int i=1;i<=n;++i)printf("%d
",a[i]);
	return 0;
}

hzoi

原文地址:https://www.cnblogs.com/Lour688/p/12899617.html