(File IO): input:team.in output:team.out
时间限制: 1000 ms 空间限制: 128000 KB 具体限制
Goto ProblemSet
题目描述
和他的朋友组成一个团队去旅行了。他们每个人都准备了一个背包,用来装旅行用的物品。他们的背包有两个特点:
- 每个人的背包能装无限多的物品,每种物品有一个价值,但只能装一件;
- 每个人都很有个性,所以每个人的背包不会完全相同。
的团队中有 个人,那么对于整个团队,背包价值和最大是多少呢?
输入
第一行两个整数
,表示团队的人数和物品的数量。
接下来一行
个整数,表示每件物品的价值
。
数据保证不会出现有空背包人的出现。
输出
一个整数,整个团队背包价值的最大值。
样例输入
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
数据范围限制
%的数据
。
%的数据
。
%的数据
。
输出请注意使用
位整数(
中的
,
中的
)。
提示
样例解释:
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题
用
表示能组成重量
的不同方法的种数
那么
方程:
;
最后贪心加答案
代码
#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);
}