POJ 3263 Tallest Cow(差分数组)

题目链接:点击这里
在这里插入图片描述
在这里插入图片描述

题目中 “at least as tall as”, “cow A can see cow B” 的意思是: h [ A + 1 ]   . . . . . .   h [ B 1 ] < h [ A ] h [ B ]    ( A < B ) h[A+1] \ ... ...\ h[B-1] < h[A] \leq h[B]\ \ (A < B)

根据题目中"Each cow has a positive integer height", “determine its maximum possible height”,很自然地想到贪心,一开始全部置为最高,然后根据出现的 A , B A, B 可以互相看得见(即 A , B A, B 之间的都比 A , B A, B 矮),将 A , B A, B 中间的数都减 1 1

注意 A , B A, B 只能出现一次,重复出现不操作。此时便是最优解。

数据不强,暴力即可:

#include<iostream>
#include<algorithm>
#include<string>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<utility>

using namespace std;
typedef long long ll;
const int MOD = 10000007;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
const int maxn = 10010;
int N, I, H, R, A, B, h[maxn];
map<pair<int,int>, bool> mmp;

int main()
{
	scanf("%d%d%d%d", &N, &I, &H, &R);
	for(int i = 1; i <= N; ++i)
		h[i] = H;
	
	while(R--)
	{
		scanf("%d%d", &A, &B);
		if(A>B)	swap(A,B);
		
		if(mmp[make_pair(A,B)])	continue;
		
		for(int i = A + 1; i < B; ++i)
			h[i]--;
		mmp[make_pair(A,B)] = true;	
	}
	
	for(int i = 1; i <= N; ++i)
		printf("%d\n", h[i]);
	
	return 0;
}

参考链接:https://blog.csdn.net/wcxyky/article/details/97233372

看了很多差分的题解,感觉下面的这个才是正经差分。

题目中的 R R 对关系实际上是牛之间身高的相对大小关系。

具体来说,我们建立一个数组 C [   ] C[\ ] ,数组中起初全为0。若一条关系指明 A A B B 可以互相看见 ( A < B ) (A<B) ,则把数组 C [   ] C[\ ] 中下标为 A + 1 A+1 B 1 B-1 的数都减去 1 1 ,意思是在 A A B B 中间的牛,身高至少要比它们小 1 1 。因为第 I I 头牛是最高的,所以最终 C [ I ] C[I] 一定为 0 0 。其他的牛与第 I I 头牛的身高差距就体现在数组 C [   ] C[\ ] 中。换言之,最后第 i i 头牛的身高就等于 H + C [ i ] H+C[i]

如果我们朴素执行把数组 C [   ] C[\ ] 中下标为 A + 1 A+1 B 1 B-1 的数都减去 1 1 的操作,那么整个算法的时间复杂度为 O ( N M ) O(NM) ,复杂度过高。

一个简单而高效的做法是差分数组,将上述对区间的操作转换为对端点的操作,时间复杂度从O(n)降为O(1)。

额外建立一个数组 f [   ] f[\ ] ,对于每对 A A B B ,令 f [ A + 1 ] f[A+1] 减去 1 1 f [ B ] f[B] 加上 1 1

最后, C [   ] C[\ ] 就等于 f [   ] f[\ ] 的前缀和。

补充知识:差分数组:点击这里

#include<iostream>
#include<algorithm>
#include<string>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<utility>

using namespace std;
typedef long long ll;
const int MOD = 10000007;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
const int maxn = 10010;
int N, I, H, R, A, B, f[maxn];
map<pair<int,int>, bool> mmp;

int main()
{
	scanf("%d%d%d%d", &N, &I, &H, &R);
	
	while(R--)
	{
		scanf("%d%d", &A, &B);
		if(A>B)	swap(A,B);
		
		if(mmp[make_pair(A,B)])	continue;
		
		f[A+1]--;
		f[B]++;
		mmp[make_pair(A,B)] = true;	
	}
	
	int tot = 0;
	for(int i = 1; i <= N; ++i)
	{
		tot += f[i];	//f[]的前缀和 
		printf("%d\n", H + tot);
	}
	
	return 0;
}
发布了711 篇原创文章 · 获赞 104 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/qq_42815188/article/details/104103062