codeforces830A

Posted pandaking

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces830A相关的知识,希望对你有一定的参考价值。

题意:有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的主要内容,如果未能解决你的问题,请参考以下文章

AC日记——830A - Office Keys

[Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3)][C. Playing Piano](代码片段

c_cpp Codeforces片段

Codeforces 86C Genetic engineering(AC自动机+DP)

CodeForces 1005D Polycarp and Div 3(思维贪心dp)

(Incomplete) Codeforces 394 (Div 2 only)