题解 CF799D Field expansion

有趣的 BFS 题。

首先发现,一个数最多乘 \(2^{17}\) 次后超过上限,所以我们可以考虑 BFS。

\(a\) 数组元素从大到小排序,定义 \((x,y,t)\) 表示当前长为 \(x\),宽为 \(y\),操作了 \(t\) 次。每次操作将两个数中没超过上限的乘上 \(a_i\)

由于可以旋转 \(90^\circ\),把长宽交换一下再跑一遍。

复杂度 \(O(2^{17})\)

code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
ll a,b,h,w,n,x[N],ans=1e9;
bool cmp(int p,int q){return p>q;}
struct node{
  ll x,y,t;
  node(ll x=0,ll y=0,ll t=0):x(x),y(y),t(t){}
};
map<pair<ll,ll>,int>mp;
queue<node>q;
void get(node nw){
  if(!mp.count(make_pair(nw.x,nw.y))){
    mp[make_pair(nw.x,nw.y)]=1;
    q.push(nw);
  }
}
void solve(ll aa,ll bb){
  mp.clear();
  while(!q.empty())q.pop();
  ll fir=min(h,aa),sec=min(w,bb);
  q.push(node(fir,sec,0));
  mp[make_pair(fir,sec)]=1;
  while(!q.empty()){
    node u=q.front(),nw;q.pop();
    if(u.x==aa&&u.y==bb){
      ans=min(ans,u.t);
      break;
    }if(u.t==n)continue;
    if(u.x<aa){
      nw=node(min(aa,u.x*x[u.t+1]),u.y,u.t+1);
      get(nw);
    }if(u.y<bb){
      nw=node(u.x,min(bb,u.y*x[u.t+1]),u.t+1);
      get(nw);
    }
  }
}
int main(){
  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  cin>>a>>b>>h>>w>>n;
  for(int i=1;i<=n;++i)cin>>x[i];
  sort(x+1,x+n+1,cmp);
  solve(a,b);solve(b,a);
  if(ans==1e9)cout<<-1<<endl;
  else cout<<ans<<endl;
  return 0;
}

posted @ 2023-07-17 21:41  HQJ2007  阅读(33)  评论(0)    收藏  举报