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.
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.
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.
3 3 2 4 4
2 5 4 10
1
3 3 3 3 5
2 3 5 4 2
0
5 5 1 2 3
2 2 3
-1
3 4 1 1 3
2 3 2
3
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
/**
* Codeforces
* Problem#799D
* Accepted
* Time: 31ms
* Memory: 2500k
*/
#include <bits/stdc++.h>
using namespace std;
typedef bool boolean; int a, b, c, d, n;
int* arr; typedef class Data {
public:
int nc;
int nd;
int step; Data():nc(), nd(), step() { }
Data(long long nc, long long nd, int step):step(step) {
this->nc = min(nc, (long long)a);
this->nd = min(nd, (long long)b);
} boolean isfin() {
return nc >= a && nd >= b;
} boolean operator < (Data b) const {
if(nc != b.nc) return nc < b.nc;
return nd < b.nd;
}
}Data; inline void init() {
scanf("%d%d%d%d%d", &a, &b, &c, &d, &n);
arr = new int[(n + )];
for(int i = ; i <= n; i++) {
scanf("%d", arr + i);
}
} set<Data> se;
queue<Data> que;
inline int bfs(int c, int d) {
Data s(c, d, );
if(s.isfin()) return ;
while(!que.empty()) que.pop();
que.push(s);
while(!que.empty()) {
Data e = que.front();
que.pop();
// printf("e:%d %d %d\n", e.nc, e.nd, e.step); if(e.nc < a) {
Data eu(e.nc * 1LL * arr[e.step + ], e.nd, e.step + );
// printf("%d %d %d\n", eu.nc, eu.nd, eu.step);
if(eu.isfin()) return eu.step;
if(eu.step < n && !se.count(eu))
que.push(eu), se.insert(eu);
} if(e.nd < b) {
Data eu(e.nc, e.nd * 1LL * arr[e.step + ], e.step + );
// printf("%d %d %d\n", eu.nc, eu.nd, eu.step);
if(eu.isfin()) return eu.step;
if(eu.step < n && !se.count(eu))
que.push(eu), se.insert(eu);
}
}
return -;
} inline void solve() {
sort(arr + , arr + n + , greater<int>());
while(n && arr[n] == ) n--;
int res1 = bfs(c, d), res2 = bfs(d, c);
if(res1 == - && res2 == -) puts("-1");
else if(res1 == - || res2 == -) printf("%d\n", max(res1, res2));
else printf("%d\n", min(res1, res2));
} int main() {
init();
solve();
return ;
}
Field expansion(bfs)
当 $a_i$ 大于2时,因为 $\log_3 10^5 \leqslant 11$,所以暴力枚举的次数不会超过 $2^{22}$,不过这是很松的界了,因为一边满了后不会再往这边放了。当 $a_i$ 等于2时,可以直接判。
Code
/**
* Codeforces
* Problem#799D
* Accepted
* Time: 15ms
* Memory: 2428k
*/
#include <bits/stdc++.h>
using namespace std;
#define smin(a, b) a = min(a, b)
typedef bool boolean;
const signed int inf = 1e9; int a, b, c, d, n;
int* arr; inline void init() {
scanf("%d%d%d%d%d", &a, &b, &c, &d, &n);
arr = new int[(n + )];
for(int i = ; i <= n; i++) {
scanf("%d", arr + i);
}
} int res = ;
int deplimit = ;
void dfs(int dep, int nc, int nd) {
// printf("%d %d %d\n", dep, nc, nd);
if(nc >= a && nd >= b) {
deplimit = dep, smin(res, dep);
// cout << dep << endl;
return;
}
if(dep == n) return;
if(arr[dep + ] == ) {
deplimit = dep;
while(nc < a && dep < n) nc <<= , dep++;
while(nd < b && dep < n) nd <<= , dep++;
if(nc < a || nd < b) return;
// cout << dep << endl;
smin(res, dep);
}
if(dep == deplimit) return;
long long nnc = nc * 1LL * arr[dep + ], nnd = nd * 1LL * arr[dep + ];
if(nc < a) dfs(dep + , smin(nnc, (long long)a), nd);
if(nd < b) dfs(dep + , nc, smin(nnd, (long long)b));
} inline void solve() {
sort(arr + , arr + n + , greater<int>());
while(n && arr[n] == ) n--;
dfs(, c, d), dfs(, d, c);
printf("%d\n", (res < ) ? (res) : (-));
} int main() {
init();
solve();
return ;
}
Codeforces 799D Field expansion - 搜索 - 贪心的更多相关文章
- Codeforces 799D Field expansion(随机算法)
Field expansion [题目链接]Field expansion [题目类型]随机化算法 &题解: 参考自:http://www.cnblogs.com/Dragon-Light/p ...
- Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2) D. Field expansion
D. Field expansion time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- codeforces Gym 100338E Numbers (贪心,实现)
题目:http://codeforces.com/gym/100338/attachments 贪心,每次枚举10的i次幂,除k后取余数r在用k-r补在10的幂上作为候选答案. #include< ...
- [Codeforces 1214A]Optimal Currency Exchange(贪心)
[Codeforces 1214A]Optimal Currency Exchange(贪心) 题面 题面较长,略 分析 这个A题稍微有点思维难度,比赛的时候被孙了一下 贪心的思路是,我们换面值越小的 ...
- [CQOI2012]模拟工厂 题解(搜索+贪心)
[CQOI2012]模拟工厂 题解(搜索+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327574 链接题目地址:洛谷P3161 BZOJ P26 ...
- 【codeforces 799D】Field expansion
[题目链接]:http://codeforces.com/contest/799/problem/D [题意] 给你长方形的两条边h,w; 你每次可以从n个数字中选出一个数字x; 然后把h或w乘上x; ...
- 【动态规划】【滚动数组】【搜索】Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2) D. Field expansion
显然将扩张按从大到小排序之后,只有不超过前34个有效. d[i][j]表示使用前i个扩张,当length为j时,所能得到的最大的width是多少. 然后用二重循环更新即可, d[i][j*A[i]]= ...
- Codeforces 799 D. Field expansion
题目链接:http://codeforces.com/contest/799/problem/D 因为${a_i>=2}$那么一个数字至多操作${log_{2}^{max(a,b)/min(h, ...
- 【贪心+DFS】D. Field expansion
http://codeforces.com/contest/799/problem/D [题意] 给定长方形的两条边h和w,你可以从给出的n个数字中随意选出一个x,把h或者w乘上x(每个x最多用一次) ...
随机推荐
- vue中把table导出表格excel
1.首先下载2个js,我的百度网盘有 2.安装依赖 npm install -S file-saver xlsx(这里其实安装了2个依赖) npm install -D script-loader 3 ...
- 字符串ASCII码排序
在对接第三方支付渠道的时候,第三方会要求参数按照ASCII码从小到大排序. 如下是渠道方有关生成签名规则的java代码示例: //初始化0010merkey.private文件: String mer ...
- 突然pom.xml中引用的jar包出错。
在你的本地仓库中,用window搜索包含.lastupdated的文件,全部删除!然后再去项目上maven ------update project
- ==与Equals的作用
string str1 = "Blackteeth"; string str2 = str1; string str3 = "Blackteeth"; Cons ...
- 10 enumerate()在字典,列表中的用法详解
1.字典 li = {"alex"," aric","Alex","Tony","rain"}for ...
- hdu5489 树状数组+dp
2015-10-06 21:49:54 这题说的是个给了一个数组,然后删除任意起点的一个连续的L个数,然后求最长递增子序列<是递增,不是非递减>,用一个树状数组维护一下就ok了 #incl ...
- 激活win10
网盘地址 http://pan.baidu.com/s/1nvc5I1V 里面是2个东西,一个是rar解压缩软件,一个是激活工具本体 一个解压缩软件,一个激活工具的压缩包 安装解压软件,就是WINRA ...
- MQ的使用场景
一.消息队列概述消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构.目前使用较多的消息队列有ActiveMQ,RabbitM ...
- Flask内置URL变量转换器
Flask内置URL变量转换器: 转换器通过特定的规则执行,”<转换器: 变量名>”.<int: year>把year的值转换为证书,因此我们可以在视图函数中直接对year变量 ...
- 什么是redis,redis简介
redis是一个key-value存储系统.包括string(字符串).list(链表).set(集合).zset(sorted set --有序集合)和hash(哈希类型). 高可用分布式集群 一, ...