题目链接:http://codeforces.com/contest/799/problem/D
In one of the games Arkady is fond of the game process happens on a rectangular field. In the game process Arkady can buy extensions for his field, each extension enlarges one of the field sizes in a particular number of times. Formally, there are n extensions, the i-th of them multiplies the width or the length (by Arkady's choice) by ai. Each extension can't be used more than once, the extensions can be used in any order.
Now Arkady's field has size h × w. He wants to enlarge it so that it is possible to place a rectangle of size a × b on it (along the width or along the length, with sides parallel to the field sides). Find the minimum number of extensions needed to reach Arkady's goal.
The first line contains five integers a, b, h, w and n (1 ≤ a, b, h, w, n ≤ 100 000) — the sizes of the rectangle needed to be placed, the initial sizes of the field and the number of available extensions.
The second line contains n integers a1, a2, ..., an (2 ≤ ai ≤ 100 000), where ai equals the integer a side multiplies by when the i-th extension is applied.
Print the minimum number of extensions needed to reach Arkady's goal. If it is not possible to place the rectangle on the field with all extensions, print -1. If the rectangle can be placed on the initial field, print 0.
3 3 2 4 4 2 5 4 10
1
3 3 3 3 5 2 3 5 4 2
0
5 5 1 2 3 2 2 3
-1
3 4 1 1 3 2 3 2
3
In the first example it is enough to use any of the extensions available. For example, we can enlarge h in 5 times using the second extension. Then h becomes equal 10 and it is now possible to place the rectangle on the field.
题目大意:
给你两个矩形,然后给你一堆的操作数,每次可以令后一个矩形的长或者宽增加对应的倍数。问你最小的操作数是多少,使得后一个矩形能够包括第一个矩形。
思路:
本来想的就是搜索但是,深搜的话log2(100000)=17,那么搜索2^34机会超时。看见一个博客学到一种剪枝方法.因为倍数会大于等于2,那么每次找到第一个等于2的值,下面都是2.所以这下面的就是单线操作,不会有分支。而前面的操作log3(100000)=11,2^22这样就能在1s内跑完。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int N =1e5+5;
ll mul[N];
ll a,b,h,w,n;
ll dfs(ll hh,ll ww,ll nn)
{
int ans1=-1,ans2=-1;
if(hh>=a&&ww>=b)
return n-nn;
if(nn==0)
return -1;
if(mul[nn]==2)//如果目前是2,那么再往下搜索都是2,所以给宽加倍或者长加倍都是一样的
{
if(hh<a)
return dfs(hh*2,ww,nn-1);//都是单线操作
return dfs(hh,ww*2,nn-1);
}
if(hh<a)
ans1= dfs(hh*mul[nn],ww,nn-1);//而从这里每次都会分出很多支路
if(ww<b)
ans2=dfs(hh,ww*mul[nn],nn-1);
if(ans1==-1||ans2==-1)
return max(ans1,ans2);
return min(ans1,ans2);
}
int main()
{
ios::sync_with_stdio(false);
cin>>a>>b>>h>>w>>n;
for(int i=1;i<=n;i++)
{
cin>>mul[i];
}
sort(mul+1,mul+1+n);
ll ans1=dfs(h,w,n);
swap(a,b);
ll ans2=dfs(h,w,n);
if(ans1==-1 || ans2==-1) cout<< max(ans1, ans2)<<endl;
else cout<<min(ans1, ans2)<<endl;
cout<<ans1<<endl;
return 0;
}