2020.02.16普及C组模拟赛7(第三题)

3.团队背包(team)

题目描述

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

  1. 每个人的背包能装无限多的物品,每种物品有一个价值,但只能装一件;
  2. 每个人都很有个性,所以每个人的背包不会完全相同。
    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 输出请注意使用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
#include
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(总结)

谢谢

你可能感兴趣的:(赛后分析)