zoukankan      html  css  js  c++  java
  • P1987 摇钱树

    题意:有n棵摇钱树,k天,每天可砍一棵并获得其金币

          每棵树初始有$a_i$个金币,每天减少$b_i$个

       问k天得到的最多金币数

    这题很明显是DP(锻炼自己的机会来了QAQ)

    设$f[i][j]$代表前i棵数,到第j天所得最大值

    $f[i][j]=max(f[i-1][j],f[i-1][j-1]+a[i]-(j-1)*b[i])$   666

    但是跑完样例发现

    f[3][2]=44

    f[3][3]=43!!!

    what???

    咋多了一天答案反而减少了??

    输出DP过程,发现$a[i]-(j-1)*b[i]$可能是负的!!

    但实际上一棵树不可能有负数个金币

    所以判断若是负数让其等于0

    这还不够,f[3][3]=44.......应该是47

    假设我们有3棵树且要选全部,每棵价值和每次消耗分别为$m1,m2,m3;b1,b2,b3;$则$总价值=m1+m2+m3-k1*b1-k2*b2-k3*b3$,

    很明显我们要选消耗大的啊  

    所以排序后,47自然就出来了qaq

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    #define int long long
    #define olinr return
    #define _ 0
    #define love_nmr 0
    #define DB double
    int n;
    int k;
    struct node
    {
        int num;
        int down;
        friend bool operator < (const node &a,const node &b)
        {
            return a.down>b.down;
        }
    }a[1050];
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
            if(ch=='-')
                f=-f;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            x=(x<<1)+(x<<3)+(ch^48);
            ch=getchar();
        }
        return x*f;
    }
    inline void put(int x)
    {
        if(x<0)
        {
            x=-x;
            putchar('-');
        }
        if(x>9)
            put(x/10);
        putchar(x%10+'0');
    }
    int f[1050][1050];
    signed main()
    {
        while(5201314)
        {
            n=read();
            k=read();
            if(!n&&!k) break;
            memset(f,0,sizeof f);
            for(int i=1;i<=n;i++)
                a[i].num=read();
            for(int i=1;i<=n;i++)
                a[i].down=read();
            sort(a+1,a+n+1);
            for(int j=1;j<=k;j++)
                for(int i=1;i<=n;i++)
                {
                    int x=a[i].num-(j-1)*a[i].down;
                    x=x>0? x:0;
                    f[i][j]=max(f[i-1][j],f[i-1][j-1]+x);
                }
            int ans=0;
            for(int i=1;i<=n;i++)
                ans=max(ans,f[n][i]);
            put(ans);
            putchar('
    ');
        }
        olinr ~~(0^_^0)+love_nmr;
    }
    /*
    3 3
    10 20 30
    4 5 6
    0 0
    4 3
    20 30 40 50
    2 7 6 5
    */
  • 相关阅读:
    前端百度地图开发使用总结
    换电脑后如何同步git本地仓库及分支
    vue mint-ui初次使用总结
    git学习入门总结
    深夜,当音乐响起,数据在MySQL中静静的疯狂计算
    且说Tomcat、Servlet、JSP和Spring
    国庆与中秋7天死磕Web的时光
    Android编程初涉,以控制摄像头为例
    谈现阶段如何形成可行的健康生活习惯方案
    说Java网络编程
  • 原文地址:https://www.cnblogs.com/olinr/p/9573734.html
Copyright © 2011-2022 走看看