1. 程式人生 > 實用技巧 >【GOJ 3032】司愁之路

【GOJ 3032】司愁之路

題目

正解

先排序,然後依次考慮以下幾種情況:

  1. 如果目前最好的方案的指數比最大的期望要大,那就兩兩抵消,分數加一;
  2. 如果目前最低的方案的指數比最低的期望要大,那就兩兩抵消,分數加一;
  3. 如果目前最好的方案的指數比最大的期望要小,那就用最差的抵消最好的,分數加一;
  4. 如果目前最好的方案的指數和最大的期望一樣,一樣用最差的抵消最好的,這樣可以保留儘量大的方案,而且最大的方案與最小的期望抵消後的收益會把之前用最差的抵消最好的的損耗填補回來,所以這樣的方案一定比大對大、小對小的方案要優。

時間複雜度 \(O(n\log_2n)\)

程式碼

#include<bits/stdc++.h>
namespace my_std {
	using namespace std;
	#define writesp(x) write(x),putchar(' ')
	#define writeln(x) write(x),putchar('\n')
	#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;
}