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.
题意
将原 h×w 的矩形扩展,使得其能够放置 a×b 的矩形。每次扩展可以从给定的 n ( n≤100000 ) 个数中选择一个数 Ai ,将 h→h⋅Ai 或者 w→w⋅Ai ,其中每个数最多只能使用一次,问最少扩展多少次能满足条件,或不可能。
解题思路
首先可以想到,对于同样地对原矩形扩展 X 次,使用 n 个数中最大的 X 个数对矩形进行扩展必然是最优的。因此,对 n 个数从小到大进行排序,并优先选用可用的最大数。
给定的 n 个数对原 h×w 矩形进行扩展,则每次可以将 h 或 w 扩展 Ai 倍。因此,朴素地使用搜索的复杂度将可能达到 O(2100000) 。但是,对于 2≤Ai ,且 1≤a,b,h,w≤100000 ,故 log2100000≈17 ,即复杂度实际应该在 O(234) 。当然,这仍然无法满足。
考虑对问题进行优化,当经过处理的原矩形 H×W 使得可用的 Ai 都为 2 时,此时无需考虑将 2 如何分配的问题,当 H 或 W 尚有不足时,直接 ×2 即可;同时 ⌈log3100000⌉=11 , O(222) 可在 1000 ms 内解决。故特判 2 可将问题复杂度缩小到可解范围。
代码
#include<bits/stdc++.h>
using namespace std;
int a, b, h, w, n, A[100010];
int dfs(long long h, long long w, int idx)
{
if(h>=a&&w>=b) return n-idx;
if(idx==0) return -1;
if(A[idx] == 2)
{
if(h<a) return dfs(h*2, w, idx-1);
return dfs(h, w*2, idx-1);
}
else
{
int ansh = -1, answ = -1;
if(h<a)
ansh = dfs(h*A[idx], w, idx-1);
if(w<b)
answ = dfs(h, w*A[idx], idx-1);
if(ansh==-1 || answ==-1) return max(ansh, answ);
return min(ansh, answ);
}
}
int main()
{
scanf("%d %d %d %d %d",&a,&b,&h,&w,&n);
for(int i=1;i<=n;i++)
scanf("%d",&A[i]);
sort(A+1, A+n+1);
int ansl, ansr;
ansl = dfs(h, w, n);
swap(a, b);
ansr = dfs(h, w, n);
if(ansl==-1 || ansr==-1) printf("%d\n", max(ansl, ansr));
else printf("%d\n", min(ansl, ansr));
}