D. Field expansion
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard 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.
log2(1e5)<17,所以在最坏情况下,最多只会用上34条边
然而枚举每次extension是扩大w,还是h,一共有234种情况,直接暴力显然TLE
法①: DP
d[i][j]=k:使用了最大的i个extension,w=j时,h的最大值为k
d[i][j]=max(d[i−1][j]∗a[i],d[i−1][j/a[i]])
d[0][w]=h,d[0][other]=0
每次状态转移完就判断能否放进a∗b的物品,因为i<=34,O(n)
法②: 枚举
log2(1e5)<17,然而log3(1e5)<11
枚举所有大于2的extension,O(222),得到的w,h,只需要知道log2(ah)和log2(bw)就能知道还需要多少个2
DP代码
#include<stdio.h>
#include <iostream>
#include<stdlib.h>
#include<algorithm>
#include<vector>
#include<deque>
#include<map>
#include<set>
#include<queue>
#include<math.h>
#include<string.h>
#include<string>
using namespace std;
#define ll long long
#define pii pair<int,int>
const int inf = 1e9 + 7;
const int N = 1e5+5;
int ext[N];
ll d[N];
int slove(int a,int b,int w,int h,int n){
if((w>=a&&h>=b)||(w>=b&&h>=a)){
return 0;
}
sort(ext,ext+n,greater<int>());
fill(d,d+N,0);
d[w]=h;
for(int i=0,ed=min(34,n);i<ed;++i){
ll x=ext[i];
for(int j=N-3;j>=0;--j){
ll w=j*x,h=d[j];
if((w>=a&&h>=b)||(w>=b&&h>=a)){
return i+1;
}
if(j*x<N){
d[j*x]=max(d[j*x],d[j]);
}
d[j]=max(d[j],d[j]*ext[i]);
w=j,h=d[j];
if((w>=a&&h>=b)||(w>=b&&h>=a)){
return i+1;
}
}
}
return -1;
}
int main()
{
//freopen("/home/lu/Documents/r.txt","r",stdin);
//freopen("/home/lu/Documents/w.txt","w",stdout);
int a,b,h,w,n;
while(~scanf("%d%d%d%d%d",&a,&b,&h,&w,&n)){
for(int i=0;i<n;++i){
scanf("%d",&ext[i]);
}
printf("%d\n",slove(a,b,h,w,n));
}
return 0;
}