【GOJ 3032】司愁之路

题目

正解

先排序,然后依次考虑以下几种情况:

  1. 如果目前最好的方案的指数比最大的期望要大,那就两两抵消,分数加一;
  2. 如果目前最低的方案的指数比最低的期望要大,那就两两抵消,分数加一;
  3. 如果目前最好的方案的指数比最大的期望要小,那就用最差的抵消最好的,分数加一;
  4. 如果目前最好的方案的指数和最大的期望一样,一样用最差的抵消最好的,这样可以保留尽量大的方案,而且最大的方案与最小的期望抵消后的收益会把之前用最差的抵消最好的的损耗填补回来,所以这样的方案一定比大对大、小对小的方案要优。

时间复杂度 (O(nlog_2n))

代码

#include<bits/stdc++.h>
namespace my_std {
	using namespace std;
	#define writesp(x) write(x),putchar(' ')
	#define writeln(x) write(x),putchar('
')
	#define mem(x,v) memset((x),(v),sizeof(x))
	#define pb push_back
	#define fir first
	#define sec second
	#define MP make_pair
	#define inv(x,p) qpow((x),(p-2),(p))
	typedef long long LL;
	typedef unsigned long long ULL;
	const int inf=INT_MAX;
	inline LL qpow(LL x,LL y,LL mod=1e9+7) {
		LL ans=1;
		while(y) {
			if(y&1) {
				ans=x*ans%mod;
			}
			x=x*x%mod,y>>=1;
		}
		return ans;
	}
	inline LL read() {
		LL sum=0,f=0;
		char c=getchar();
		while(!isdigit(c)) {
			f|=(c=='-'),c=getchar();
		}
		while(isdigit(c)) {
			sum=sum*10+(c^48),c=getchar();
		}
		return f?-sum:sum;
	}
	void write(LL k) {
		if(k<0) {
			putchar('-'),k=-k;
		}
		if(k>9) {
			write(k/10);
		}
		putchar(k%10+48);
	}
}
using namespace my_std;
const int N=1000005;
int a[N],b[N];
int n=read(),ans;
bool cmp(int c,int d) {
	return c>d;
}
int main() {
	for(int i=1; i<=n; i++) {
		a[i]=read();
	}
	for(int i=1; i<=n; i++) {
		b[i]=read();
	}
	sort(a+1,a+n+1,cmp),sort(b+1,b+n+1,cmp);
	int i=1,j=1,l=n,r=n;
	while(i<=l) {
		if(b[i]>a[j]) {
			ans++,i++,j++;
		} else if(b[l]>a[r]) {
			ans++,l--,r--;
		} else {
			if(b[l]<a[j]) {
				ans--;
			}
			l--,j++;
		}
	}
	write(ans);
	return 0;
}
原文地址:https://www.cnblogs.com/Sam2007/p/13452333.html