1. 程式人生 > 其它 >P4531[CTSC2005]魔術眼鏡盒題解

P4531[CTSC2005]魔術眼鏡盒題解

考慮兩個比較好想貪心。

$ 1. $ 既然要數量最大,優先從小選的比較優 。

$ 2. $ 兩個比較大小接近的放在一起比較優 。

現將原陣列排序。

手玩幾組樣例發現,為了滿足貪心原則 $ 1 , 2 $ ,最後的答案肯定是從 $ 1 $ 開始的連續一段。

可以考慮列舉連續一段的端點,判定是否合法即可。

複雜度 $ O(n^2) $ ,實際遠遠達不到。

#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int rd(){
	int x=0,f=1;char ch=getchar();
	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
	while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
vector<int> s1,s2;
int Ans_cnt,Now_s;
int n,m,s,num;

signed main()
{
//	   s1.resize(55000);
//	   s2.resize(55000);
//	   freopen("7.in","r",stdin);
//	   freopen("Ans.out","w",stdout);
	   n=rd();
	   m=rd();
	   s=rd();
	   for(int i=1;i<=n;i++)
	   {
	       int a;
	       a=rd();
	   	   s1.push_back(a);
	   }
	   for(int i=1;i<=m;i++)
	   {
           int a;
	   	   a=rd();
	   	   s2.push_back(a);
	   }
       if(s1.size()<s2.size()) s1.swap(s2);
	   sort(s1.begin(),s1.end());
	   sort(s2.begin(),s2.end());
	   int sum=0;
	   for(vector<int>::iterator it=s1.begin();it!=s1.end();it++)
       {
       	   int cnt=num;
       	   int Maxn=0,xuan;
		   if(it==s1.end()) continue;
		   vector<int>::iterator it1=it;
       	   vector<int>::iterator it2=s2.begin();
       	   int now_sum=sum;
       	   while(1)
       	   {
       	   	     Maxn=max(*it1,*it2);
       	         if((now_sum+Maxn)*Maxn>s) break;
       	         xuan=Maxn;
       	         now_sum+=Maxn;
				 cnt+=2;
				 it1++;
				 it2++;
				 if(it1==s1.end()||it2==s2.end()) break;
		   }
	   	   if(cnt>Ans_cnt)
		   {
		   	  Now_s=xuan*now_sum;
		   	  Ans_cnt=cnt;
		   }
           else	if(cnt==Ans_cnt)
		   {
		   	  Now_s=min(Now_s,xuan*now_sum);
		   }
		   sum+=*it;
		   num++;
		   if(sum*Maxn>s||it1==s1.end()) break;
	   }
	   cout<<Ans_cnt<<" "<<Now_s<<endl;
}