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

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

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), where ai equals the integer a side multiplies by when the i-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, print 0.

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

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.


题目大意:

给你一个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 __int64
ll 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);
    }
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值