(纪中)032. 团队背包(team)【DP】

(File IO): input:team.in output:team.out
时间限制: 1000 ms 空间限制: 128000 KB 具体限制
Goto ProblemSet


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

  1. 每个人的背包能装无限多的物品,每种物品有一个价值,但只能装一件;
  2. 每个人都很有个性,所以每个人的背包不会完全相同。
    D a A DaA 的团队中有 M M 个人,那么对于整个团队,背包价值和最大是多少呢?

输入
第一行两个整数 M N M、N ,表示团队的人数和物品的数量。
接下来一行 N N 个整数,表示每件物品的价值 w i 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 30 %的数据 1 < = M , N < = 15 1<=M,N<=15
60 60 %的数据 1 < = M < = 200 1 < = N < = 100 1<=M<=200,1<=N<=100
100 100 %的数据 1 < = M < = 1 , 000 , 000 1 < = N < = 500 0 < w i < = 50 1<=M<=1,000,000,1<=N<=500,0<wi<=50
输出请注意使用 64 64 位整数( P a s c a l Pascal 中的 I n t 64 Int64 C + + C++ 中的 l o n g l o n g 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题
f [ i ] f[i] 表示能组成重量 i i 的不同方法的种数
那么 D P DP 方程:
f [ i ] = f [ i ] + f [ i a [ j ] ] f[i]=f[i]+f[i-a[j]] ;
最后贪心加答案


代码

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#include<iomanip>
#include<cmath>
using namespace std;
long long m,n,w[600],a[30000],t,maxn,ans;
int main(){
	freopen("team.in","r",stdin);
    freopen("team.out","w",stdout);
    scanf("%d%d",&m,&n);
    maxn=0;
    for(long long i=1;i<=n;i++)
    {
    	scanf("%d",&w[i]);	 
    	maxn=maxn+w[i];
	}
	a[0]=1;
	for(long long i=1;i<=n;i++)
	{
		for(long long j=maxn;j>=0;j--)
		{
			if(j>=w[i])  
			a[j]=a[j]+a[j-w[i]];
		}
	}
	ans=0;
	for(long long i=maxn;i>=0;i--)
	{
		if(a[i]<=m) 
		{
			m=m-a[i];
			ans=ans+a[i]*i;
		}
		else
		{
			ans=ans+i*m;
			break;
		}
	}
	printf("%lld",ans);
}
发布了73 篇原创文章 · 获赞 5 · 访问量 1804

猜你喜欢

转载自blog.csdn.net/kejin2019/article/details/104364835