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

【CodeForces】 830A Office Keys

时间:2018-02-23 00:45:28      阅读:258      评论:0      收藏:0      [点我收藏+]

标签:图片   wan   nts   person   div   size   algo   最小   name   

传送门

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

标签:图片   wan   nts   person   div   size   algo   最小   name   

原文地址:https://www.cnblogs.com/Fang-Hao/p/8460599.html

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