zoukankan      html  css  js  c++  java
  • [日常训练]training

    Description

    一条线上有n栋楼,第i栋楼有h_i层,每层有1个价值为v_i的物品.

    可以花费1个单位时间完成以下3种移动:

    1.在同一栋楼中向上或者向下走一层;

    2.如果此刻在顶楼,可以通往1楼;

    3.从当前楼移动到相邻楼的同层.如果相邻楼没有当前位置高,则会落到相邻楼的顶层。

    初始时在第一栋楼的顶层,m单位时间可以移动,拿去物品不需要时间,且一个物品被拿一次之后就会消失。
    求能获得的最大的总价值.

    Input

    第一行两个正整数n,m.
    以下n行每行两个整数表示h_iv_i

    Output

    输出一行一个整数表示最大的总价值。

    Sample Input

    3 3 2 1 1 5 3 4

    Sample Output

    14

    HINT

    å1;leq;n,h_i;leq;10^6,0;leq;v_i;leq;10^6,m;leq;$sum_{i=1}^{n}{h_i}$
    Solution

    枚举最远到达的那栋楼,然后贪心.

    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<stack>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define N 1000005
    using namespace std;
    typedef long long ll;
    struct house{
        ll h,v,n;
    }a[N];
    int n,u;
    ll cnt[N],v[N],m,k,ans,sum,tmp;
    inline int read(){
        int ret=0;char c=getchar();
        while(!isdigit(c))
            c=getchar();
        while(isdigit(c)){
            ret=(ret<<1)+(ret<<3)+c-'0';
            c=getchar();
        }
        return ret;
    }
    inline ll rd(){
        ll ret=0LL;char c=getchar();
        while(!isdigit(c))
            c=getchar();
        while(isdigit(c)){
            ret=(ret<<1LL)+(ret<<3LL)+(ll)(c-'0');
            c=getchar();
        }
        return ret;
    }
    inline bool cmp(house x,house y){
        if(x.v!=y.v) return x.v>y.v;
        return x.n<y.n;
    }
    inline void init(){
        n=read();m=rd()+1LL;
        if((ll)(n)>m) n=(int)(m);
        for(int i=1;i<=n;++i){
            a[i].h=rd();v[i]=a[i].v=rd();a[i].n=(ll)(i);
        }
        sort(a+1,a+1+n,cmp);
        for(int i=1;i<=n;++i){
            ++cnt[a[i].n];--m;
        }
        for(int i=1;i<=n&&m;++i){
            tmp=min(a[i].h-1LL,m);
            cnt[a[i].n]+=tmp;m-=tmp;
        }
        for(int i=1;i<=n;++i)
            ans+=cnt[i]*v[i];
        for(u=1;u<=n;++u)
            if(cnt[a[u].n]!=a[u].h) break;
        sum=ans;
        for(int k=n;k>1;--k){
            m=cnt[k];sum-=cnt[k]*v[k];
            for(;u<=n;++u)
                if(a[u].n<k){
                    tmp=min(a[u].h-cnt[a[u].n],m);
                    cnt[a[u].n]+=tmp;m-=tmp;
                    sum+=a[u].v*tmp;
                    if(!m) break;
                }
            ans=max(ans,sum);
        }
        printf("%lld
    ",ans);
    }
    int main(){
        freopen("training.in","r",stdin);
        freopen("training.out","w",stdout);
        init();
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
  • 相关阅读:
    Spring>autoWire
    hibernate>多对多关联映射
    Hibernate>一级缓存
    Hibernate>component映射和复合主键映射
    Struts2>类型转换
    hibernate>继承
    hibernate>悲观锁和乐观锁
    Spring>Bean的作用域
    Struts2>defaultactionref
    数据库的隔离级别
  • 原文地址:https://www.cnblogs.com/AireenYe/p/6131144.html
Copyright © 2011-2022 走看看