团队背包(team)

题目描述

贝里斯和他的奶牛朋友组成一个团队去旅行了。他们每头奶牛都准备了一个背包,用来装旅行用的物品。他们的背包有两个特点:

1.每头奶牛的背包能装无限多的物品,每种物品有一个价值,但只能装一件;

2.每头奶牛都很有个性,所以每头奶牛的背包不会完全相同。

贝里斯的团队中有 M 头奶牛,那么对于整个团队,背包价值和最大是多少呢?

输入

从文件 team.in 中读入数据。

从文件 team.in 中读入数据。

第一行两个整数 M、N,表示团队的奶牛数和物品的数量。

接下来一行 N 个整数,表示每件物品的价值 wi。

数据保证不会出现有空背包奶牛的出现。

输出

输出到文件 team.out 中。

输出到文件 team.out 中。

一个整数,整个团队背包价值的最大值。

样例数据
输入 #1 复制
2 3
2 7 1
输出 #1 复制
19
输入 #2 复制
8 4
1 2 3 4
输出 #2 复制
58
数据范围限制

对于 30% 的数据,满足 1<=M,N<=15。

对于 60% 的数据,满足 1<=M<=200,1<=N<=100。

对于 100% 的数据,满足 1<=M<=1,000,000,1<=N<=500,0<wi<=50。

输出请注意使用 64 位整数(C++ 中的 long long)。

提示

样例1解释

19=(2+7+1)+(2+7)

样例2解释

58=(1+2+3+4)+(2+3+4)+(1+3+4)+(1+2+4)+(3+4)+(1+2+3)+(2+4)+(2+3)

思路:这是一道动态规划的题,可以每个物品循环一遍,因为数据只用25000,所以可以每个点都循环一遍,f[j]+=f[j-w[i]],f[i]代表承受i的重量有多少种可能数,(注意:由于承受0的重量也有1种可能,所以f[0]要被负初始值为1)然后从25000循环到0,如果m>0且还有可能每被算,且f[i]>0,那么ans+=i*min(m,f[i]),并m-=min(m,f[i]),最后输出一下就行了

AC代码:

#include<bits/stdc++.h>
using namespace std;
long long n,m,cnt; 
long long a[505],
f[25005],s[25005];
long long ans;
int main()
{
    freopen("team.in","r",stdin);
    freopen("team.out","w",stdout);    
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%lld",&a[i]);
    }
    f[0]=1;
    for(int i=1;i<=m;i++)
    {
        for(int j=25000;j>=a[i];j--)
        {
            f[j]+=f[j-a[i]];
        }
    }
    for(int i=25000;i>=0;i--)
    {
        if(f[i]!=0)
        {
            s[++cnt]=i;
        }
    }
    for(int i=1;i<cnt&&n>0;i++)
    {
        ans+=min(f[s[i]],n)*s[i],n-=min(f[s[i]],n);
    }
    printf("%lld",ans);
    return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值