装备合成
通过集思广益,我总结了一些不同的解法。
法一:二分答案
一般最大最小值问题都可以考虑一下对答案进行二分。
1、若能合成k件装备,那么k-1,k-2,...都能够合成。所以我们要找到11110000中最右边的1。
2、判断k件装备能否成立。设消耗的2a3b有m件,那么4a1b的有k-m件
列不等式0<=2m+4(k-m)<=x 0<=3m+k-m<=y 0<=m<=k且m为整数
化简得4k-m<=2m<=2k 0<=2m<=y-k且m为整数
即max(4k-m,0)<=2m<=min(y-k,2k)
另外由于m是整数,2m为偶数,所以如果max(4k-m,0)=min(y-k,2k)且为奇数,也是不符合的。
主要代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll x,y; bool check(ll m){ ll l=max(4*m-x,ll(0)),r=min(2*m,y-m); if (l<r) return true; else if (l==r && l%2==0) return true; else return false; } int main(){ int t; cin>>t; while (t--){ cin>>x>>y; ll left=0,right=y+1; while (left+1<right){ ll mid=left+(right-left>>1); if (check(mid)) left=mid; else right=mid; } printf("%lld\n",left); } return 0; }
法二:线性规划或者说观察单调性。如图
主要代码
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll x,y; int check(ll m){ ll n=min((x-2*m)/4,y-3*m); return m+n; } int main(){ int t; cin>>t; while (t--){ cin>>x>>y; ll m3; double m=1.0*(4*y-x)/10; m3=min(x/2,y/3); if (m3<m) printf("%d\n",m3); else if (m<=0) printf("%d\n",y); else { ll m1=floor(m),m2=ceil(m); m1=check(m1); m2=check(m2); if (m1>m2) printf("%lld\n",m1); else printf("%lld\n",m2); } } return 0; }
法三:三分(ps:现在还不会三分,以后学会了再补)