CodeForces 830A Office Keys

Posted fang-hao

tags:

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

传送门

codeforces

luogu

题目描述

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.

技术分享图片

 

 

思路

  首先读入后,按照位置分别排序,然后处理一个dis数组,表示第i个人拿了第j把钥匙后去办公室的路程。 然后就是一个01背包,最开始的时候人是瓷的,写了三重循环,一直TLE,附上磁珠代码233333

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<math.h>
using namespace std;
int n,k,p;
int man[1005];
int key[2005];
int dis[1005][2005];
int dp[1005][2005];
inline int cmp(int a,int b){
    return a<b;
}
int minn(int a,int b){
    if(a>=b)return b;
    return a;
}
int maxx(int a,int b){
    if(a>=b)return a;
    return b;
}
int main(){
    //freopen("1.in","r",stdin);
    cin>>n>>k>>p;
    for(register int i=1;i<=n;i++){
        cin>>man[i];
    }
    for(register int i=1;i<=k;i++){
        cin>>key[i];
    }
    sort(man+1,man+n+1,cmp);
    sort(key+1,key+k+1,cmp);
    for(register int i=1;i<=n;i++){
        for(register int j=1;j<=k;j++){
            dis[i][j]=fabs(man[i]-key[j])+fabs(key[j]-p);
            dp[i][j]=999999999;
        }
    }
    dp[0][0]=0;
    //cout<<"fuck"<<endl;
    for(register int i=1;i<=n;i++){  //1-ige re 
        for(register int j=i;j<=k;j++){ //1-j zhongxuanze
            int xx=minn(j,n);
            for(register int kk=i;kk<=xx;kk++){
                if(kk<1)continue;
                dp[i][j]=minn(dp[i][j],maxx(dp[i-1][kk-1],dis[kk][j]));
//                cout<<i<<‘ ‘<<j<<‘ ‘<<kk<<endl;
//                cout<<dp[i][j]<<‘ ‘<<dp[i-1][kk]<<‘ ‘<<dis[kk][j]<<endl<<endl;
            }
        }
    }
    // while(1){
    //     int x,y;
    //     cin>>x>>y;
    //     cout<<dp[x][y]<<endl;
    // }
    int ans=999999999;
    for(register int i=n;i<=k;i++){
        ans=min(ans,dp[n][i]);
    }
    cout<<ans<<endl;
}

  当时用kk来表示i-1个人一共拿到第kk把钥匙是的最大步数的最小值,就是因为枚举这个kk然后挂了,后来发现不需要枚举kk,因为dp[i][j]只能从dp[i][j-1]和dp[i-1][j-1]两种情况转移过来,分别表示不选第j把钥匙和第i个人选了第j把钥匙的情况。

  可以得到状态转移方程:

              dp[i][j]=min(dp[i][j-1],max(dp[i-1][j-1],dis[i][j]));

  还有,初始化很重要qwq,所有的dp[0][i]都等于0,剩下的所有都是2147483647。

 

附上代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<math.h>
using namespace std;
int n,k,p;
int man[1005];
int key[2005];
int dis[1005][2005];
int dp[1005][2005];
inline int cmp(int a,int b){
    return a<b;
}
int minn(int a,int b){
    if(a>=b)return b;
    return a;
}
int maxx(int a,int b){
    if(a>=b)return a;
    return b;
}
int main(){
    //freopen("1.in","r",stdin);
    cin>>n>>k>>p;
    for(register int i=1;i<=n;i++){
        cin>>man[i];
    }
    for(register int i=1;i<=k;i++){
        cin>>key[i];
    }
    sort(man+1,man+n+1,cmp);
    sort(key+1,key+k+1,cmp);
    for(register int i=0;i<=n;i++){
        for(register int j=0;j<=k;j++){
            dis[i][j]=fabs(man[i]-key[j])+fabs(key[j]-p);
            dp[i][j]=2147483647;
        }
    }
    for(register int i=0;i<=k;i++){
        dp[0][i]=0;
    }
    //cout<<"fuck"<<endl;
    for(register int i=1;i<=n;i++){  //1-ige re 
        for(register int j=1;j<=k;j++){ //1-j zhongxuanze
            dp[i][j]=minn(dp[i][j-1],maxx(dp[i-1][j-1],dis[i][j]));
        }
    }
    // while(1){
    //     int x,y;
    //     cin>>x>>y;
    //     cout<<dp[x][y]<<endl;
    // }
    int ans=2147483647;
    for(register int i=n;i<=k;i++){
        ans=min(ans,dp[n][i]);
    }
    cout<<ans<<endl;
}

 

以上是关于CodeForces 830A Office Keys的主要内容,如果未能解决你的问题,请参考以下文章

codeforces830A

Codeforces 702 D Road to Post Office

Codeforces 830A. Office Keys (背包dp+贪心) / (二分+贪心)

Codeforces Gym100187C Very Spacious Office 贪心 堆

模拟NEERC15 A Adjustment Office (2015-2016 ACM-ICPC)(Codeforces GYM 100851)

Codeforces VK Cup Finals #424 Div.1 A. Office Keys(DP)