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 }
以上是关于codeforces830A的主要内容,如果未能解决你的问题,请参考以下文章
[Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3)][C. Playing Piano](代码片段
Codeforces 86C Genetic engineering(AC自动机+DP)