Codeforces 799D Field expansion - 搜索 - 贪心

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.


  题目大意 给定一个w × h的矩形,每次可以将w或h乘上ai(ai不能重复使用,并且与顺序无关)。问至少扩充多少次可以使得这个矩形中包含一个a × b的子矩形,如果无解输出-1。

  因为 $w$ 和 $h$ 呈指数级增长,考虑爆搜。

  可以知道题目要求最少的,所以先用大的ai更划算。因此可以先将ai排一次序。

  既然是求最少,又确定是搜索,考虑 bfs。加上判重。好了这道题AC了。

  不知道为啥原来写了一个假的复杂度证明还觉得它很对?

  不难发现它涉及到的状态数不会超过下面的状态数乘 34。不过这也是一个非常松的界。

Code

 1 /**
 2  * Codeforces
 3  * Problem#799D
 4  * Accepted
 5  * Time: 31ms
 6  * Memory: 2500k
 7  */
 8 #include <bits/stdc++.h>
 9 using namespace std;
10 typedef bool boolean;
11 
12 int a, b, c, d, n;
13 int* arr;
14 
15 typedef class Data {
16     public:
17         int nc;
18         int nd;
19         int step;
20         
21         Data():nc(0), nd(0), step(0) {        }
22         Data(long long nc, long long nd, int step):step(step) {
23             this->nc = min(nc, (long long)a);
24             this->nd = min(nd, (long long)b);
25         }
26         
27         boolean isfin() {
28             return nc >= a && nd >= b;
29         }
30         
31         boolean operator < (Data b) const {
32             if(nc != b.nc)    return nc < b.nc;
33             return nd < b.nd;
34         }
35 }Data;
36 
37 inline void init() {
38     scanf("%d%d%d%d%d", &a, &b, &c, &d, &n);
39     arr = new int[(n + 1)];
40     for(int i = 1; i <= n; i++) {
41         scanf("%d", arr + i);
42     }
43 }
44 
45 set<Data> se; 
46 queue<Data> que;
47 inline int bfs(int c, int d) {
48     Data s(c, d, 0);
49     if(s.isfin())    return 0;
50     while(!que.empty())    que.pop();
51     que.push(s);
52     while(!que.empty()) {
53         Data e = que.front();
54         que.pop();
55 //        printf("e:%d %d %d\n", e.nc, e.nd, e.step);
56         
57         if(e.nc < a) {
58             Data eu(e.nc * 1LL * arr[e.step + 1], e.nd, e.step + 1);
59 //            printf("%d %d %d\n", eu.nc, eu.nd, eu.step);
60             if(eu.isfin())    return eu.step;
61             if(eu.step < n && !se.count(eu))
62                 que.push(eu), se.insert(eu);
63         }
64         
65         if(e.nd < b) {
66             Data eu(e.nc, e.nd * 1LL * arr[e.step + 1], e.step + 1);
67 //            printf("%d %d %d\n", eu.nc, eu.nd, eu.step);
68             if(eu.isfin())    return eu.step;
69             if(eu.step < n && !se.count(eu))
70                 que.push(eu), se.insert(eu);
71         }
72     }
73     return -1;
74 }
75 
76 inline void solve() {
77     sort(arr + 1, arr + n + 1, greater<int>());
78     while(n && arr[n] == 1)    n--;
79     int res1 = bfs(c, d), res2 = bfs(d, c);
80     if(res1 == -1 && res2 == -1)    puts("-1");
81     else if(res1 == -1 || res2 == -1)    printf("%d\n", max(res1, res2));
82     else printf("%d\n", min(res1, res2));
83 }
84 
85 int main() {
86     init();
87     solve();
88     return 0;
89 }
Field expansion(bfs)

  当 $a_i$ 大于2时,因为 $\log_3 10^5 \leqslant 11$,所以暴力枚举的次数不会超过 $2^{22}$,不过这是很松的界了,因为一边满了后不会再往这边放了。当 $a_i$ 等于2时,可以直接判。

Code

 1 /**
 2  * Codeforces
 3  * Problem#799D
 4  * Accepted
 5  * Time: 15ms
 6  * Memory: 2428k
 7  */
 8 #include <bits/stdc++.h>
 9 using namespace std;
10 #define smin(a, b) a = min(a, b)
11 typedef bool boolean;
12 const signed int inf = 1e9;
13 
14 int a, b, c, d, n;
15 int* arr;
16 
17 inline void init() {
18     scanf("%d%d%d%d%d", &a, &b, &c, &d, &n);
19     arr = new int[(n + 1)];
20     for(int i = 1; i <= n; i++) {
21         scanf("%d", arr + i);
22     }
23 }
24 
25 int res = 35;
26 int deplimit = 20;
27 void dfs(int dep, int nc, int nd) {
28 //    printf("%d %d %d\n", dep, nc, nd);
29     if(nc >= a && nd >= b) {
30         deplimit = dep, smin(res, dep);
31 //        cout << dep << endl;
32         return;
33     }
34     if(dep == n)    return;
35     if(arr[dep + 1] == 2) {
36         deplimit = dep;
37         while(nc < a && dep < n)    nc <<= 1, dep++;
38         while(nd < b && dep < n)    nd <<= 1, dep++;
39         if(nc < a || nd < b)    return;
40 //        cout << dep << endl;
41         smin(res, dep);
42     }
43     if(dep == deplimit)    return;
44     long long nnc = nc * 1LL * arr[dep + 1], nnd = nd * 1LL * arr[dep + 1];
45     if(nc < a)    dfs(dep + 1, smin(nnc, (long long)a), nd);
46     if(nd < b)    dfs(dep + 1, nc, smin(nnd, (long long)b));
47 }
48 
49 inline void solve() {
50     sort(arr + 1, arr + n + 1, greater<int>());
51     while(n && arr[n] == 1)    n--;
52     dfs(0, c, d), dfs(0, d, c);
53     printf("%d\n", (res < 35) ? (res) : (-1));
54 }
55 
56 int main() {
57     init();
58     solve();
59     return 0;
60 }
posted @ 2017-08-02 15:45  阿波罗2003  阅读(...)  评论(...编辑  收藏