多重背包,记下拥有同一券同一价值的奖品的数量,当做同一类 P,W<=10,最多10*10=100种
#include<iostream>
#include<string.h>
using
namespace
std
;
#define MAX 100010
int
dp
[
MAX
];
int
nu
[
20
][
20
];
int
n
,
m
;
struct
node
{
int
val
;
//价值
int
cost
;
//花费
int
num
;
}
no
[
110
];
void
zeronepack
(
int
cost
,
int
val
)
{
for
(
int
i
=
m
;
i
>=
cost
;
i
--
)
dp
[
i
]
=
max
(
dp
[
i
],
dp
[
i
-
cost
]
+
val
);
}
void
compack
(
int
cost
,
int
val
)
{
for
(
int
i
=
cost
;
i
<=
m
;
i
++
)
dp
[
i
]
=
max
(
dp
[
i
],
dp
[
i
-
cost
]
+
val
);
}
void
multipack
(
int
cost
,
int
val
,
int
num
)
{
if
(
cost
*
num
>=
m
)
compack
(
cost
,
val
);
else
{
int
k
=
1
;
while
(
k
<
num
)
{
zeronepack
(
k
*
cost
,
k
*
val
);
num
-=
k
;
k
<<=
1
;
}
zeronepack
(
num
*
cost
,
num
*
val
);
}
}
int
main
()
{
cin
>>
n
>>
m
;
int
u
,
v
;
memset
(
nu
,
0
,
sizeof
(
nu
));
for
(
int
i
=
0
;
i
<
n
;
i
++
)
{
cin
>>
u
>>
v
;
nu
[
u
][
v
]
++
;
}
n
=
0
;
for
(
int
i
=
0
;
i
<
110
;
i
++
)
no
[
i
].
num
=
0
;
for
(
int
i
=
0
;
i
<
11
;
i
++
)
{
for
(
int
j
=
0
;
j
<
11
;
j
++
)
{
if
(
nu
[
i
][
j
])
{
no
[
n
].
val
=
j
;
no
[
n
].
cost
=
i
;
no
[
n
++
].
num
=
nu
[
i
][
j
];
}
}
}
memset
(
dp
,
0
,
sizeof
(
dp
));
for
(
int
i
=
0
;
i
<
n
;
i
++
)
{
multipack
(
no
[
i
].
cost
,
no
[
i
].
val
,
no
[
i
].
num
);
}
cout
<<
dp
[
m
]
<<
endl
;
}