2018.10.09 NOIP模擬 好數(雙向搜尋)
阿新 • • 發佈:2018-12-14
傳送門 直接雙向搜尋出兩邊可行解,然後把兩邊的可行解合併起來得出答案就行了。 注意合併的時候可以利用排序和單調性優化時間複雜度。 直接列舉合併是的。 但排序之後隨著集合中的乘積的增大,集合中的可行個數顯然是單調遞減的。 這樣就可以方便的統計答案了。 程式碼:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll read(){
ll ans=0;
char ch=getchar();
while(!isdigit (ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
int k,tot=0,pos=0,mid;
ll lim,pri[30],divv[30];
vector<ll>mul1,mul2;
map<ll,int>S;
inline void dfs1(int pos,ll mul){
mul1.push_back(mul);
for(ll i=pos;i<=mid;++i){
ll b=mul;
while (lim/b>=divv[i])b*=divv[i],dfs1(i+1,b);
}
}
inline void dfs2(int pos,ll mul){
mul2.push_back(mul);
for(ll i=pos;i<=tot;++i){
ll b=mul;
while(lim/b>=divv[i])b*=divv[i],dfs2(i+1,b);
}
}
int main(){
k=read(),lim=read();
for(int i=1;i<=k;++i)pri[i]=read();
for(int i=1;i<=k;i+=2)divv[ ++tot]=pri[i];
mid=tot;
for(int i=2;i<=k;i+=2)divv[++tot]=pri[i];
dfs1(1,1),S.clear(),dfs2(mid+1,1),sort(mul1.begin(),mul1.end()),sort(mul2.begin(),mul2.end());
ll ans1=0,ans2=0,pos=mul2.size()-1;
for(int i=0;i<mul1.size();++i){
while(lim/mul1[i]<mul2[pos])--pos,mul2.pop_back();
ans1+=pos+1,ans2=max(ans2,mul2[pos]*mul1[i]);
}
cout<<ans2<<'\n'<<ans1;
return 0;
}