码迷,mamicode.com
首页 > 其他好文 > 详细

codeforces830A

时间:2018-11-14 01:05:51      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:lld   就是   有一个   好用   个人   最大值   int   分享   []   

题意:有n个人在一条直线上,在这条直线上有k把钥匙(n<=k),有一个门,要求每个人都携带一把钥匙来开这张门!求他们需要的最短时间!

 

我这次感觉虽然看懂了题,但是我第二次想的时候就跑题了啊,这道题可以说是二分中的经典,最大值最小化,也就是开要使得开这张门最长的那个时间最短,但是我二分不会写judge,所以只能用dp做了,这道题还有一个显然的结论,就是他们是有顺序的,每个人(从1到n)取得的钥匙号码是必须递增的。

 

状态设置是dp[i][j],i表示前i个人,j表示前j个钥匙,那么这个整个的状态的意思可以理解为前i个人取前j把钥匙的时间的最大值的最小值。那么dp[i][j]=min(dp[i][j-1],max(dp[i-1][j-1],abs(a[i]-b[j])+abs(bj[]-p)));

注意一下范围,最好用long long

下面是代码(二分的先鸽了,下次学了再写):

接下来是代码(这道题主要是状态的设置,其他都是很难)

技术分享图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 int n,m;
 5 ll p;
 6 ll a[1100];
 7 ll b[2100];
 8 ll dp[1100][2100];
 9 int main(){
10     scanf("%d%d%lld",&n,&m,&p);
11     for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
12     for(int i=1;i<=m;i++) scanf("%lld",&b[i]);
13     sort(a+1,a+n+1);
14     sort(b+1,b+m+1);
15     for(int i=1;i<=n;i++){
16         dp[i][i]=max(dp[i-1][i-1],abs(a[i]-b[i])+abs(b[i]-p));
17         for(int k=i+1;k<=m;k++)
18             dp[i][k]=min(dp[i][k-1],max(dp[i-1][k-1],abs(a[i]-b[k])+abs(b[k]-p)));
19     }
20     cout<<dp[n][m]<<endl;
21     return 0;
22 }
View Code

 

codeforces830A

标签:lld   就是   有一个   好用   个人   最大值   int   分享   []   

原文地址:https://www.cnblogs.com/pandaking/p/9955654.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!