您的位置:首页 > 其它

Codeforces Round #424 -(二分&贪心)||dp-D. Office Keys

2017-07-19 21:07 387 查看
http://codeforces.com/contest/831/my

给定n个人的位置,和k个钥匙,再给你办公室的位置。

每个人需要拿一个钥匙,然后到办公室,问你每个人都到达办公室的最短时间。

1 dp

dp[i][j]为前i个人,拿了前j个的最小值。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2005;
ll a[maxn], b[maxn], n, k, p;
ll dp[maxn][maxn];

int main(void)
{
while(cin >> n >> k >> p)
{
for(int i = 1; i <= n; i++)
scanf("%I64d", &a[i]);
for(int i = 1; i <= k; i++)
scanf("%I64d", &b[i]);
sort(a+1, a+1+n);
sort(b+1, b+1+k);
dp[0][0] = 0;
for(int i = 1; i <= n; i++)
for(int j = i; j <= k; j++)
{
if(i == j)
dp[i][j] = max(dp[i-1][j-1], abs(a[i]-b[j])+abs(b[j]-p));
else
dp[i][j] = min(dp[i][j-1], max(dp[i-1][j-1], abs(a[i]-b[j])+abs(b[j]-p)));
}
printf("%I64d\n", dp
[k]);
}
return 0;
}


2 贪心。

我们发现,最远那个地方老是拖后腿,他需要把最远的钥匙给拿了,才能保证时间最短(如果别人拿需要更多时间。)

所以我们就贪心一个规律

排序后

每个人都从左边拿。

这样最远的肯定拿到最远的。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=2005;
int m,n,p;
int a[maxn];
int b[maxn];
bool solve(ll x){
bool vis[maxn];
memset(vis,false,sizeof(vis));
int cnt=0;
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
{  if(vis[j]) continue;
if(1ll*abs(a[i]-b[j])+1ll*abs(p-b[j])<x)
{cnt++;
vis[j]=true;
break;}
}
if(cnt==m)
return true;
return false;
}
int check(long long x)
{
int i;
int now=0;
for(i=0;i<m;i++)
{
while(abs(b[now]-a[i])+abs(p-b[now])>x)
{
now++;
if(now>=n)
return 0;
}
now++;
}
return 1;
}
int main()
{   scanf("%d%d%d",&m,&n,&p);
for(int i=0;i<m;i++){
scanf("%d",&a[i]);
}
sort(a,a+m);
for(int i=0;i<n;i++){
scanf("%d",&b[i]);
}
sort(b,b+n);
ll r=0x3f3f3f3f3f3f3f3f;
ll l=0;
ll ans=0;
while(l<=r){
ll mid=(l+r)/2;
if(solve(mid)){
ans=mid;
r=mid-1;
}
else
l=mid+1;
}
printf("%lld\n",ans-1);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: