3.团队背包(team)
题目描述
DaA 和他的朋友组成一个团队去旅行了。他们每个人都准备了一个背包,用来装旅行用的物品。他们的背包有两个特点:
- 每个人的背包能装无限多的物品,每种物品有一个价值,但只能装一件;
- 每个人都很有个性,所以每个人的背包不会完全相同。
DaA 的团队中有M 个人,那么对于整个团队,背包价值和最大是多少呢?
输入
第一行两个整数M、N,表示团队的人数和物品的数量。
接下来一行N 个整数,表示每件物品的价值wi。
数据保证不会出现有空背包人的出现。
输出
一个整数,整个团队背包价值的最大值。
样例输入
Sample Input 1:
2 3
2 7 1
Sample Input 2:
8 4
1 2 3 4
样例输出
Sample Output 1:
19
Sample Output 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 位整数(Pascal 中的Int64,C++中的long long)。
提示
【样例解释】
19=(2+7+1)+(2+7)
58=(1+2+3+4)+(2+3+4)+(1+3+4)+(1+2+4)+(3+4)+(1+2+3)+(2+4)+(2+3)
正解
从这题目中,我们可以知道,这题是dp。但又和普通的01背包不一样,所以我们会怀疑这道题不是dp,但是我告诉你,这道题的正解就和01背包差不多
AC代码
#include<iostream>
#include<cstdio>
using namespace std;
long long m,n,w[505];
long long a,s,f[25005];
int main()
{
freopen("team.in","r",stdin);
freopen("team.out","w",stdout);
cin>>m>>n;
for(int i=1;i<=n;i++)
{
cin>>w[i];
s+=w[i];//把所有价值加起来(最后的结果就是最大的价值)
}
f[0]=1;//初始值
for(int i=1;i<=n;i++)
for(int j=s;j>=w[i];j--)
f[j]+=f[j-w[i]];//dp
for(int i=s;i>=1;i--)
if(m>f[i])//当m的值大于价值为i的个数时
{
a+=f[i]*i;//加上价值为i的个数*i(价值为i的个数*i=所有价值为i的和)
m-=f[i];//减去它的个数
}
else//当m的值小于于价值为i的个数时
{
a+=i*m;//加上价值为i的个数*m(最大是m个)
break;//退出(因为已经加了m个了)
}
cout<<a;
return 0;
}
下面附本次比赛的其他题目
2020.02.16普及C组模拟赛7(第一题)
2020.02.16普及C组模拟赛7(第二题)
2020.02.16普及C组模拟赛7(第三题)
2020.02.16普及C组模拟赛7(第四题)
2020.02.16普及C组模拟赛7(总结)