牛牛的背包(牛客网·贪心)

~~~题目链接~~~
来源:牛客网

题目描述
牛牛有最多50个物品,每个物品有一个type标号,并且有一个taste值,现在要求选择若干个物品放进背包使得x * y最大,x为选择的不同type的数量,y为总的taste值之和

输入描述:
第一行输入一个整数n表示物品的数量(1 ≤ n ≤ 50)
第二行输入 n个整数typei表示每个物品的类型(1 ≤ typei ≤ 100)
第三行输入n个整数tastei(-100000 ≤ tastei ≤ 100000)

输出描述:
输出一个整数代表x*y

示例1

输入

2
1 2
4 7

输出

22

示例2

输入

2
1 1
-1 -1

输出

0

示例3

输入

3
1 2 3
7 4 -1

输出

30

这一题明显可以发现,背包的容量是没有上限的,所以想装多少就装多少
于是对于一个物品:
·如果它的taste值为正数,那么装进包里xy是会增大的
·如果taste值是负数,那么我们需要看装进这个物品x
y会不会增大
显然,taste是负数时,type如果出现过,那x*y一定减小,如果没有出现过,做一个比较即可
这种算法也被叫做贪心(和坤行为 ),本题满足取到了局部最优就能得到整体的最优的前提

需要注意的是,只有先取完了所有正数,取负数的时候才能进行比较
(比较时需要用上已有的type数量)
并且对于一个物品具有新的type值,那么taste值越大越好(考虑负数的情况)

#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;

struct node
{
    int type, taste;
} a[55];//结构体存值

bool cmp(node x, node y)
{
    return x.taste > y.taste;
}

bool vis[110];//储存有没有见过这个type

int main()
{
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i].type);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i].taste);
    sort(a + 1, a + n + 1, cmp);//排序,一定要排序
    //只有先装了所有的正数,取负数的时候才能比较
    
    int x = 0, y = 0;
    for (int i = 1; i <= n; i++)
    {
        if (a[i].taste >= 0)//正数,x*y增大大大
        {
            y += a[i].taste;
            if (!vis[a[i].type])//判断是不是新的type值
            {
                x++;
                vis[a[i].type] = 1;
            }
        }
        else if (!vis[a[i].type] && (x + 1) * (y + a[i].taste) > x * y)//没见过并且拿了可以增大x*y
        {
            x++;
            y += a[i].taste;
            vis[a[i].type] = true;
        }
    }
    
    printf("%d", x * y);
    return 0;
}

—————————————————————————————————————————————————————
喜欢的朋友们多多关注我哦,欢迎私聊哦

如果有想让我发题解的题也欢迎讨论

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值