(File IO): input:team.in output:team.out
时间限制: 1000 ms 空间限制: 128000 KB 具体限制
Goto ProblemSet
题目描述
D
a
A
DaA
DaA 和他的朋友组成一个团队去旅行了。他们每个人都准备了一个背包,用来装旅行用的物品。他们的背包有两个特点:
- 每个人的背包能装无限多的物品,每种物品有一个价值,但只能装一件;
- 每个人都很有个性,所以每个人的背包不会完全相同。
D a A DaA DaA 的团队中有 M M M 个人,那么对于整个团队,背包价值和最大是多少呢?
输入
第一行两个整数
M
、
N
M、N
M、N,表示团队的人数和物品的数量。
接下来一行
N
N
N 个整数,表示每件物品的价值
w
i
wi
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
30%的数据
1
<
=
M
,
N
<
=
15
1<=M,N<=15
1<=M,N<=15。
60
60
60%的数据
1
<
=
M
<
=
200
,
1
<
=
N
<
=
100
1<=M<=200,1<=N<=100
1<=M<=200,1<=N<=100。
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
1<=M<=1,000,000,1<=N<=500,0<wi<=50。
输出请注意使用
64
64
64 位整数(
P
a
s
c
a
l
Pascal
Pascal 中的
I
n
t
64
Int64
Int64,
C
+
+
C++
C++中的
l
o
n
g
l
o
n
g
long long
longlong)。
提示
样例解释:
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]
f[i]表示能组成重量
i
i
i的不同方法的种数
那么
D
P
DP
DP方程:
f
[
i
]
=
f
[
i
]
+
f
[
i
−
a
[
j
]
]
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);
}