• GHOJ 277 吃鱼


    题目描述

      小花爱吃鱼,这是全世界都知道的事情。它的好朋友编程兔给它准备了很多的零食,每一样都是小花喜欢的。当然了,里面最多的肯定是鱼。某一天编程兔给小花准备了两种鱼,一种鱼的重量是1,另一种鱼的重量是2,重量为1的鱼有不同的美味值,重量为2的鱼也有不同的美味值。现在假设小花的胃口最多能吃下不超过重量为v的鱼,小花希望吃掉的鱼的美味值总和最大。

    输入输出格式

    输入格式

      第一行是两个正整数n和v,n表示鱼的数量,v表示小花的胃口。

      接下来n行,每行两个正整数,第一个正整数表示鱼的重量(只有1和2两种可能),另一个正整数表示这条的美味值。

     

    输出格式

      一行,一个整数,表示小花能得到的最大美味值总和。

    输入输出样例

    输入样例

    3 2

    1 2

    2 7

    1 3

    输出样例

    7

    说明

    样例说明

      小花选择了第2条鱼吃,美味值是7。

    数据规模

      对于60%的数据,1≤n≤2000。

      对于100%的数据,1≤n≤30000,1≤v≤60000,每条鱼的美味值不超过10000。

    题解  

      这道题其实是一道暴力枚举题,但是有一种贪心做法还是可取的。

      下面把重量为1的鱼称为鱼1,重量为2的鱼称为鱼2.

      首先尽可能吃价值高的鱼1,吃完还没饱再尽可能吃价值高的鱼2.

      此时尝试用剩下的鱼2去换鱼1,取最优即可。

      最后要判断是否还有剩余空间。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    
    #define MAX_N 30000
    #define MAX_M 60000
    
    using namespace std;
    
    int n;
    int m;
    struct Fish
    {
        int w;
        int v;
        inline bool operator < (const Fish & x) const
        {
            if(w != x.w) return w < x.w;
            return v > x.v;
        }
    };
    Fish a[MAX_N + 5];
    int ans;
    
    int main()
    {
        scanf("%d%d", &n, &m);
        int mid = 0;
        for(register int i = 1; i <= n; ++i)
        {
            scanf("%d%d", &a[i].w, &a[i].v);
            if(a[i].w & 1) ++mid;
        }
        sort(a + 1, a + n + 1);
        int i = 0, j = mid;
        while(i < mid && i < m)
        {
            ans += a[++i].v;
        }
        while(j < n && i + (j - mid + 1 << 1) <= m)
        {
            ans += a[++j].v;
        }
        while(i >= 2 && j < n && a[i].v + a[i - 1].v <= a[j + 1].v)
        {
            ans += a[++j].v - a[i--].v - a[i--].v;
        }
        if(i < mid && i + (j - mid << 1) < m)
        {
            ans += a[++i].v;
        }
        printf("%d", ans);
        return 0;
    }
    参考程序(贪心)

      下面也附上暴力程序。只需要运用前缀和。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    
    #define MAX_N 30000
    #define MAX_M 60000
    
    using namespace std;
    
    int n;
    int m;
    struct Fish
    {
        int w;
        int v;
        inline bool operator < (const Fish & x) const
        {
            if(w != x.w) return w < x.w;
            return v > x.v;
        }
    };
    Fish a[MAX_N + 5];
    int ans;
    
    int main()
    {
        scanf("%d%d", &n, &m);
        int mid = 0;
        for(register int i = 1; i <= n; ++i)
        {
            scanf("%d%d", &a[i].w, &a[i].v);
            if(a[i].w & 1) ++mid;
        }
        sort(a + 1, a + n + 1);
        for(register int i = 1; i <= n; ++i)
        {
            a[i].v += a[i - 1].v;
        }
        m = min(m, mid + (n - mid << 1));
        for(register int i = 0; i <= m; i += 2)
        {
            if((m - i) <= mid && mid + (i >> 1) <= n)
            {
                ans = max(ans, a[m - i].v + a[mid + (i >> 1)].v - a[mid].v);
            }
        }
        printf("%d", ans);
        return 0;
    }
    参考程序(暴力枚举)
  • 相关阅读:
    C# 基础知识系列- 11 委托和事件
    C# 基础知识系列- 10 反射和泛型(二)
    C# 基础知识系列- 9 字符串的更多用法(二)
    C# 基础知识系列- 9 字符串的更多用法(一)
    C# 基础知识系列- 8 Linq最后一部分查询表达式语法实践
    C# 基础知识系列- 6 Lambda表达式和Linq简单介绍
    C# 基础知识系列- 5 反射和泛型
    C# 基础知识系列- 4 面向对象
    TLS加密远程连接Docker
    树莓派4B安装64位Linux(不用显示器键盘鼠标)
  • 原文地址:https://www.cnblogs.com/kcn999/p/10456142.html
Copyright © 2020-2023  润新知