考虑二分w,然后对前一半和后一半搜索,在统计有多少情况合法。
在前一半搜出的内容里二分即可。
和今天做的一道双端搜索题很像。好吧都一样
P4799 [CEOI2015 Day2]世界冰球锦标赛 (双端搜索)_Jack_00_的博客-优快云博客
总算有思路了,比没思路要好,但还是很菜
#include<bits/stdc++.h>
using namespace std;
long long n,m,k;
long long a[35],b[35];
bool check(long long mid) {
vector<long long>l,r;
for(int i=0;i<(1<<(n/2));i++) {
long long tot=0;
for(int j=0;j<n/2;j++) {
if(i&(1<<j)) tot+=a[j+1]+b[j+1]*mid;
}
l.push_back(tot);
}
for(int i=0;i<(1<<(n-n/2));i++) {
long long tot=0;
for(int j=0;j<(n-n/2);j++) {
if(i&(1<<j)) tot+=a[j+n/2+1]+b[j+n/2+1]*mid;
}
r.push_back(tot);
}
sort(l.begin(),l.end());
sort(r.begin(),r.end());
reverse(r.begin(),r.end());
long long sum=0;
for(int i=0;i<l.size();i++) {
int aa=lower_bound(r.begin(),r.end(),m-l[i],greater<long long>())-r.begin();
sum+=r.size()-aa;
}
return sum>=k;
}
int main() {
cin>>n>>m>>k;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>b[i];
long long l=1,r=1e13+10;
while(r>l) {
long long mid=l+r>>1;
if(check(mid)) l=mid+1;
else r=mid;
}
cout<<l-1;
return 0;
}