题目大意:
题目链接:http://10.156.31.134/contestnew.aspx?cid=123 (学校局域网)
有
m
m
m个箱子,每个箱子里最多可以取1个东西。每个东西有
a
,
b
,
v
a,b,v
a,b,v三个参数,求在满足
∑
a
≤
A
(
c
h
o
o
e
s
a
)
,
∑
b
≤
B
(
c
h
o
o
e
s
b
)
\sum a\leq A(chooes\ a),\sum b\leq B(chooes\ b)
∑a≤A(chooes a),∑b≤B(chooes b)的最大
∑
v
\sum v
∑v值。
思路:
显然分组背包。
设
f
[
i
]
[
k
]
[
l
]
f[i][k][l]
f[i][k][l]表示选到第
i
i
i个箱子,
a
,
b
a,b
a,b参数之和分别为
k
,
l
k,l
k,l的最大
∑
v
\sum v
∑v值。
枚举箱子里的东西
j
j
j,显然转移方程为
f
[
i
]
[
k
]
[
l
]
=
m
a
x
(
f
[
i
]
[
k
]
[
l
]
,
f
[
i
−
1
]
[
k
−
a
]
[
l
−
b
]
+
z
,
f
[
i
−
1
]
[
k
]
[
l
]
)
f[i][k][l]=max(f[i][k][l],f[i-1][k-a][l-b]+z,f[i-1][k][l])
f[i][k][l]=max(f[i][k][l],f[i−1][k−a][l−b]+z,f[i−1][k][l])
最终答案就是
m
a
x
{
f
[
m
]
[
i
]
[
j
]
}
max\{f[m][i][j]\}
max{f[m][i][j]}
时间复杂度
O
(
n
A
B
)
O(nAB)
O(nAB),
n
n
n表示东西的总个数。
代码:
#include <cstdio>
#include <iostream>
using namespace std;
const int M=15,N=110;
int n,m,A,B,ans,f[M][N][N],a[N],b[N],v[N],q[M][N],sum[M];
int main()
{
scanf("%d%d%d%d",&n,&m,&A,&B);
for (int i=1;i<=n;i++)
{
int x;
scanf("%d%d%d%d",&a[i],&b[i],&x,&v[i]);
q[x][++sum[x]]=i;
}
for (int i=1;i<=m;i++)
{
for (int j=1;j<=sum[i];j++)
{
int x=a[q[i][j]],y=b[q[i][j]],z=v[q[i][j]];
for (int k=x;k<=A;k++)
for (int l=y;l<=B;l++)
f[i][k][l]=max(f[i][k][l],f[i-1][k-x][l-y]+z);
}
for (int j=0;j<=A;j++)
for (int k=0;k<=B;k++)
f[i][j][k]=max(f[i][j][k],f[i-1][j][k]);
}
for (int i=0;i<=A;i++)
for (int j=0;j<=B;j++)
ans=max(ans,f[m][i][j]);
printf("%d",ans);
return 0;
}