BZOJ1034 [ZJOI2008]泡泡堂BNB[贪心]
贪心题怎么做都不会啊,果然还是考智商的
如果没有平局,很好整,直接每次从对方最小的开始找一个己方最小且比他大的,找不到就负,否则即胜,这个贪心显然是对的。
但是现在有了平局的1分,就不好这样了,因为平局的情况有时候可以选,有时候又有更优的策略。。
考虑这样一种贪心:
先比双方最小的,如果己方最小完胜对方最小,那直接把这一对去掉,加两分,因为己方最小现在不用,以后用不会更优;
如果己方最小不能完胜,考虑那他去消耗对方最大,不过在此之前先看己方最大可不可以直接干掉对方最大,否则这样就可能不优,同理己方最大大于对方最大的时候也可以直接去掉,加两分
这样以后如果己方最大也不能完胜对方最大,那考虑用最小的去消耗对方最大,这样可以保证己方最大尽可能来实现自己价值。
尝试可以发现平局的情况也可以处理。
本质还是众多人所说的类“田忌赛马”的原理。。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 #define mst(x) memset(x,0,sizeof x) 8 #define dbg(x) cerr << #x << " = " << x <<endl 9 #define dbg2(x,y) cerr<< #x <<" = "<< x <<" "<< #y <<" = "<< y <<endl 10 using namespace std; 11 typedef long long ll; 12 typedef double db; 13 typedef pair<int,int> pii; 14 template<typename T>inline T _min(T A,T B){return A<B?A:B;} 15 template<typename T>inline T _max(T A,T B){return A>B?A:B;} 16 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;} 17 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;} 18 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;} 19 template<typename T>inline T read(T&x){ 20 x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1; 21 while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x; 22 } 23 const int N=1e5+7; 24 int a[N],b[N]; 25 int n,ans,ans2; 26 27 int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout); 28 read(n); 29 for(register int i=1;i<=n;++i)read(a[i]); 30 for(register int i=1;i<=n;++i)read(b[i]); 31 sort(a+1,a+n+1),sort(b+1,b+n+1); 32 for(register int i=1,j=n,l=1,r=n;i<=j;){ 33 if(a[i]>b[l])++i,++l,ans+=2; 34 else if(a[j]>b[r])--j,--r,ans+=2; 35 else ans+=a[i]==b[r],++i,--r; 36 } 37 for(register int i=1,j=n,l=1,r=n;i<=j;){ 38 if(b[i]>a[l])++i,++l; 39 else if(b[j]>a[r])--j,--r; 40 else ans2+=b[i]==a[r]?1:2,++i,--r; 41 } 42 printf("%d %d\n",ans,ans2); 43 return 0; 44 }
总结:主要是贪心策略没有想到。。很多的贪心都是基于排序的。。也不一定就要啥高级数据结构。。不妨用排序和比较来解决序列的问题