codeforces830A (二分|DP)
来源:互联网 发布:数据库添加语句 编辑:程序博客网 时间:2024/04/27 10:29
There are n people and k keys on a straight line. Every person wants to get to the office which is located on the line as well. To do that, he needs to reach some point with a key, take the key and then go to the office. Once a key is taken by somebody, it couldn't be taken by anybody else.
You are to determine the minimum time needed for all n people to get to the office with keys. Assume that people move a unit distance per 1 second. If two people reach a key at the same time, only one of them can take the key. A person can pass through a point with a key without taking it.
The first line contains three integers n, k and p (1 ≤ n ≤ 1 000, n ≤ k ≤ 2 000, 1 ≤ p ≤ 109) — the number of people, the number of keys and the office location.
The second line contains n distinct integers a1, a2, ..., an (1 ≤ ai ≤ 109) — positions in which people are located initially. The positions are given in arbitrary order.
The third line contains k distinct integers b1, b2, ..., bk (1 ≤ bj ≤ 109) — positions of the keys. The positions are given in arbitrary order.
Note that there can't be more than one person or more than one key in the same point. A person and a key can be located in the same point.
Print the minimum time (in seconds) needed for all n to reach the office with keys.
2 4 5020 10060 10 40 80
50
1 2 101115 7
7
In the first example the person located at point 20 should take the key located at point 40 and go with it to the office located at point 50. He spends 30 seconds. The person located at point 100 can take the key located at point 80 and go to the office with it. He spends 50seconds. Thus, after 50 seconds everybody is in office with keys.
题意:一共有n个人k把钥匙,每个人都需要先拿任意一把钥匙然后在去唯一的一个咖啡厅。问最少需要多少时间才能让所有人都进入咖啡厅。
二分 + 暴力:二分答案,通过暴力判断是否符合条件。在判断过程中如果左边的一个人去拿左边的某一把钥匙不符合条件,那么它右边的人去拿这把钥匙也必然不符合条件。时间复杂度O(n*m)。
下面是代码:
#include<iostream>#include<cstring>#include<cmath>#include<cstdio>#include<algorithm>#define MAX 2005#define INF 0x3f3f3f3f*2#define ll long longusing namespace std;int a[MAX],b[MAX];int n,m,p;bool Judge(int num){int k = 0;for(int j = 0; j < n; j++){bool ok = false;for(k; k < m; k++){//cout << k << ":" << abs(a[j] - b[k]) + abs(p - b[k]) << "/";if(abs(a[j] - b[k]) + abs(p - b[k]) <= num){k++;ok = true;break;}}//cout << endl;if(!ok) return false;}/*注意数据:2 2 1056 423 8 */return true;}int main( ){//cout << INF << endl;while(cin >> n >> m >> p){for(int j = 0; j < n; j++)cin >> a[j];for(int j = 0; j < m; j++)cin >> b[j];sort(a,a + n);sort(b,b + m);/*for(int j = 0; j < n; j++)cout << a[j] << " ";cout << endl;for(int j = 0; j < m; j++)cout << b[j] << " ";cout << endl;*/ll left = -1,right = INF,mid;/*left 起点必须是-1,hack数据:1 1 111 */while((right - left) > 1){mid = left + ((right - left)>>1);//cout << mid << endl; if(Judge(mid))right = mid;elseleft = mid;}cout << right << endl;}}DP+贪心:DP[j][k]表示前j个人在前k个钥匙的范围内拿取钥匙,当计算到第k个钥匙时查看让第j个人拿会不会使得时间更优化。所以,动态转移方程式是:DP[j][k] = min(DP[j][k-1],max(abs(a[j] - b[k]) + abs(p - b[k]),DP[j - 1][k - 1]))。然后,在对于j 等于 k 的时间特殊处理一下就行了。时间复杂度O(n*m)。
下面是代码:
#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#define MAX 2002#define ll long longusing namespace std;ll DP[MAX][MAX];int a[MAX],b[MAX];ll abs(ll a){return a > 0 ? a : -a;}ll max(ll a,ll b){return a > b ? a : b;}ll min(ll a,ll b){return a > b ? b : a;}int main( ){int n,m,p;while(cin >> n >> m >> p){for(int j = 1; j <= n; j++)cin >> a[j];for(int j = 1; j <= m; j++)cin >> b[j];sort(a + 1,a + 1 + n);sort(b + 1,b + 1 + m);/*for(int j = 1; j <= n; j++)cout << a[j] << " ";cout << endl;for(int j = 1; j <= m; j++)cout << b[j] << " ";cout << endl;*/for(int j = 1; j <= n; j++){DP[j][j] = max(DP[j - 1][j - 1],abs(a[j] - b[j]) + abs(p - b[j]));for(int k = j + 1; k <= m; k++)DP[j][k] = min(max(abs(a[j] - b[k]) + abs(p - b[k]),DP[j - 1][k - 1]),DP[j][k - 1]);}/*for(int j = 1; j <= n; j++){for(int k = 1; k <= m; k++)cout << DP[j][k] << " ";cout << endl; }*/cout << DP[n][m] << endl;}}
已经荒废了几个月了,本来就很菜,现在该重新捡起来了。继续给自己加油↖(^ω^)↗。
- codeforces830A (二分|DP)
- Codeforces830A【二分+贪心】
- 【二分+贪心】Codeforces830A[Office Keys]题解
- uvalive4625(dp + 二分)
- hdu3586(二分+树形dp)
- CodeChef STRSUB(dp+二分)
- UVALive 4625 Garlands(二分答案 + DP)
- UVALive 3608 Period(二分答案+DP)
- poj3744(概率DP+矩阵二分)
- UVA - 1443 Garlands (二分+DP)
- hdu3586(树形DP+二分,割边)
- hdu3585 二分最大团(dp优化)
- 树形DP+二分(Information Disturbing HDU3586)
- 最长递增子序列!!!(DP ,二分)
- hdu 4495 - Rectangle(hash+二分+dp)
- UVALive 5983 MAGRID(二分+dp)
- hdu 4495(hash+二分+dp)
- BNUOJ-33687-Beautiful Spacing(二分+DP)
- JAVA 攻城狮 第十七天
- CentOS 7.3安装详解
- 解决通常每个套接字地址(协议/网络地址/端口)只允许使用一次
- Git 和 Github 使用教程
- css
- codeforces830A (二分|DP)
- Java学习笔记 02
- 测试
- 【脚本语言系列】关于Python基础知识__slots__,你需要知道的事
- 数据库事务的四大特性以及事务的隔离级别
- unicode gbk 转换函数
- Node.js中间件和spring boot配合使用
- Firebase-config 在android中的使用
- java.lang.ClassCastException: class com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$