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;
    }
  • 相关阅读:
    DataTable 中varchar 转换为 Double 后重新 排序。
    asp.net 后台实现删除,划掉效果
    word2007二级标题自动编号不从大标题开始的解决方法
    asp.net 多个文件同时下载
    asp 时间倒数后按钮可用
    js获取gridview模板列中textbox行列的值
    JS错误 theForm.submit();SCRIPT3: 找不到成员。
    JS验证 只能输入小数点,数字,负数。
    关于SQLServer2008数据如何导入SQL2005的解决办法,高版本数据导入低版本中。
    asp.net中TreeView的大数据加载速度优化
  • 原文地址:https://www.cnblogs.com/AireenYe/p/6131144.html
Copyright © 2011-2022 走看看