zoukankan      html  css  js  c++  java
  • P2769 猴子上树

    题目描述

    在猴村有一条笔直的山路,这条山路很窄,宽度忽略不计。有 n只猴子正站在山路上静静地观望今天来参加比赛的各位同学。用一个正整数Xi表示第i只猴子所站位置,任意两只猴子的所站位置互不相同。在这条山路的m个位置上种着一些高大的树木,正整数Yj表示第j棵树木所在的位置,任意两棵树的位置互不相同。

    正当猴子们聚精会神的欣赏各位高超编程技能 聚精会神的欣赏各位高超编程技能时,一只老虎大摇摆的走了过来。猴子们吓得直冒冷汗,第一反应就是找棵大树爬上去这样能避免被老虎咬死或者吃掉(不考虑老虎上树问题)。

    在位置a的猴子跑到在位置b的大树上,需要消耗能量为|a-b|(即 a-b的绝对值)。为了尽可能有效利用这些大树避难,每棵上至少要一只猴子。 请编程计算n只猴子全部上树最少需要消耗多能量?

    输入格式

    输入共4行。

    第1行一个整数 n,表示猴子的数量。

    第2行n个整数,i个整数个整数Xi表示第i只猴子所在的位置。

    第3行一个整数m,表示大树的数量。

    第4行m个整数,第j个整数表示第j棵大树所在的位置。

    输出格式

    输出一行,一个整数表示n只猴子全部上树最少需要消耗的能量。

    输入输出样例

    输入 #1
    3
    1 4 5
    2
    3 8
    
    输出 #1
    6
    
    输入 #2
    3
    3 1 10
    2
    8 3
    
    输出 #2
    4
    

    说明/提示

    30%的数据,1≤n≤500,1≤Xi,Yi≤10^5。

    100%的数据,1≤n≤5000,1≤m≤n,1≤Xi,Yi≤10^9。

    首先此题一定要先对两个数组排序。
    然后采用动态规划的思想,定义f[i][j]=前i只猴子上前j棵树的消耗的最小能量。
    对于转移方程:如果j==1,即只有一棵树,那么f[i][j]必然等于f[i-1][j]+abs(a[i]-b[j])
    如果j==i,即i只猴子上i棵树,又因为每棵树上必有一致猴子,f[i][i]必然等于f[i-1][i-1]+abs(a[i]-b[i])

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    int n,m,i,j; 
    
    #define ll long long
    #define INF 46116860184299739803
    
    ll mon[5005];
    ll tree[5005];
    ll f[2][5005];
    inline int read(){
        int s=0,w=1;
        char ch=getchar();
        while(ch<'0'||ch>'9'){
            if(ch=='-'){
                w=-1;
            }
            ch=getchar();
        }
        while(ch>='0'&&ch<='9'){
            s=s*10+ch-'0';
            ch=getchar();
        }
        return s*w;
    }
    
    
    int main(){
        n=read();
        for(i=1;i<=n;i++){
            mon[i]=read();
        }
        m=read();
        for(i=1;i<=m;i++){
            tree[i]=read();
        }
        sort(mon+1,mon+n+1);
        sort(tree+1,tree+m+1);
        f[1][1]=abs(mon[1]-tree[1]);
        for(i=2;i<=n;i++){
            for(j=1;j<=m;j++){
                if(j==1){
                    f[i%2][1]=f[(i-1)%2][1]+abs(mon[i]-tree[j]);
                    continue;
                }
                if(i==j){
                    f[i%2][j]=f[(i-1)%2][j-1]+abs(mon[i]-tree[j]);
                    break;
                }
                f[i%2][j]=min(f[(i-1)%2][j],f[(i-1)%2][j-1])+abs(mon[i]-tree[j]);
            }
        }
        printf("%lld
    ",f[n%2][m]);
        return 0;
    }
  • 相关阅读:
    构建CMDB的一些启发
    一个NB的安全认证机制
    SQLAlchemy
    Tornado基本使用
    Tornado源码探寻(请求到来)
    Tornado源码探寻(准备阶段)
    Tornado源码探寻(开篇)
    我的个人博客网站
    IDEA/AS快捷键收集&习惯
    ubuntu命令收集
  • 原文地址:https://www.cnblogs.com/hrj1/p/11538055.html
Copyright © 2011-2022 走看看