Codeforces 799D Field expansion【贪心+暴搜】

来源:互联网 发布:瓷砖进销存软件 编辑:程序博客网 时间:2024/06/05 02:07

D. Field expansion
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

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 aren extensions, the i-th of them multiplies the width or the length (by Arkady's choice) byai. 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 sizea × 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.

Input

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), whereai equals the integer a side multiplies by when thei-th extension is applied.

Output

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, print0.

Examples
Input
3 3 2 4 42 5 4 10
Output
1
Input
3 3 3 3 52 3 5 4 2
Output
0
Input
5 5 1 2 32 2 3
Output
-1
Input
3 4 1 1 32 3 2
Output
3
Note

In the first example it is enough to use any of the extensions available. For example, we can enlargeh in 5 times using the second extension. Thenh becomes equal 10 and it is now possible to place the rectangle on the field.


题目大意:

给你一个h*w的矩阵,每一次我们可以取一个数,使得h*这个数或者是w*这个数,使得最终的矩阵可以放下一个a*b的小矩阵。

问最少操作次数。


思路:


1、首先观察到数据范围不大,a,b的极限大小都是1e5.

那么我们考虑最坏的情况,如果我们一开始h和w都是1,a和b都是1e5.而且所有可以选择的数都是2.

那么我们需要34次操作。

如果我们能够优化一些剪枝一些,爆搜是可行方案。


2、所以我们这里贪心去选择数字,我们肯定是要先将所有数字从大到小排序的,然后取前34个最大的数字进行爆搜。

如果我们直接爆搜的话,时间复杂度是O(2^34),明显会TLE掉、

那么我们考虑,如果剩余的数字都是2的话,那么我们给谁都一样,所以就不用O(2)的去枚举这个数字乘给h还是w了。

那么对于剩下数字都是2的情况,我们暴力处理给h和w即可。

然后再优化点小小的剪枝,这个题就搞掉了。


Ac代码:

#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>using namespace std;#define ll __int64ll b[22];ll a[100050];ll A,B,h,w,n;ll cnt,output;void Dfs(ll h,ll w,ll now,ll cont){    if(cont>output)return ;    if(h>=A&&w>=B)    {        output=min(cont,output);        return ;    }    if(now==cnt)return ;    if(b[now]==2)    {        while(h<A&&now<cnt)        {            h*=b[now];            now++;            cont++;            if(cont>output)return ;        }        while(w<B&&now<cnt)        {            w*=b[now];            now++;            cont++;            if(cont>output)return ;        }        if(h>=A&&w>=B)        output=min(cont,output);        return ;    }    else    {        Dfs(h*b[now],w,now+1,cont+1);        Dfs(h,w*b[now],now+1,cont+1);    }}int main(){    while(~scanf("%I64d%I64d%I64d%I64d%I64d",&A,&B,&h,&w,&n))    {        for(ll i=0;i<n;i++)scanf("%I64d",&a[i]);        cnt=0;        sort(a,a+n);        for(ll i=n-1;i>=0;i--)        {            b[cnt++]=a[i];            if(cnt>34)break;        }        output=0x3f3f3f3f;        Dfs(h,w,0,0);        Dfs(w,h,0,0);        if(output==0x3f3f3f3f)printf("-1\n");        else printf("%I64d\n",output);    }}







0 0
原创粉丝点击