题目大意是说有3种武器,每种都有一个重量w,一个尺寸s,一个战斗系数d,另外,如果把数量分别为c1,c2,c3的3种武器合在一起用,就会得到战斗系数为d4的新武器。
现在,有1,2,3...,n量车子来运输武器,每量车子都有最大运输重量和最大运输尺寸,现在用车量来运输武器,要求出能达到的最大战斗系数。
这题很明显是一道动态规划题,初看题意感觉跟背包问题挺象的,不过那只是表面现象而已。
设f[i][n1][n2]表示用前i量车子在运 n1件1武器和n2件2武器的条件下能运的第3种武器的最大数量。
那么f[0][0][0]=0
设函数num(i,j,k)表示第i量车子在运j个1武器和k个2武器后最多再能运k个3武器,则
f[i][n1][n2]=f[i-1][n3][n4]+num(i,n1-n3,n2-n4)
具体参数的取值范围详见程序。
另外可以看到f[i]的值只于f[i-1]有关,那么可以用滚动数组来节省空间。
算出f[n]后,就可以枚举i,j了,看f[n][i][j]的情况,算出此情况下的战斗系数,这样就可以求出最大值了。
code:
#include
<
iostream
>
#include
<
string
>
using
namespace
std;
int
main( ) {
const
int
MAXN
=
501
;
int
pre[ MAXN ][ MAXN ],now[ MAXN ][ MAXN ];
int
w1,s1,d1,w2,s2,d2,w3,s3,d3,c1,c2,c3,d4,n;
int
ma,mb;
int
cases
=
0
;
while
(cin
>>
n) {
cases
++
;
if
( n
==
0
)
break
;
cin
>>
w1
>>
s1
>>
d1
>>
w2
>>
s2
>>
d2
>>
w3
>>
s3
>>
d3
>>
c1
>>
c2
>>
c3
>>
d4;
memset( pre,
255
,
sizeof
( pre ) );
d4
-=
c1
*
d1
+
c2
*
d2
+
c3
*
d3;
pre[
0
][
0
]
=
0
;
ma
=
mb
=
0
;
for
(
int
i
=
0
;i
<
n;i
++
) {
memset( now,
255
,
sizeof
( now ) );
int
cw,cs;
cin
>>
cw
>>
cs;
int
maa
=
ma,mbb
=
mb;
for
(
int
i1
=
0
;i1
<=
maa;i1
++
)
for
(
int
j1
=
0
;j1
<=
mbb;j1
++
) {
if
( pre[ i1 ][ j1 ]
<
0
)
continue
;
for
(
int
i11
=
i1,tw1
=
0
,ts1
=
0
;tw1
<=
cw
&&
ts1
<=
cs;i11
++
,tw1
+=
w1,ts1
+=
s1 )
for
(
int
j11
=
j1,tw2
=
tw1,ts2
=
ts1;tw2
<=
cw
&&
ts2
<=
cs;j11
++
,tw2
+=
w2,ts2
+=
s2 ){
if
( ma
<
i11 ) ma
=
i11;
if
( mb
<
j11 ) mb
=
j11;
int
da
=
( cw
-
tw2 )
/
w3;
int
db
=
( cs
-
ts2 )
/
s3;
if
( da
>
db ) da
=
db;
if
( now[ i11 ][ j11 ]
<
pre[ i1 ][ j1 ]
+
da )
now[ i11 ][ j11 ]
=
pre[ i1 ][ j1 ]
+
da;
}
}
for
(
int
i11
=
0
;i11
<=
ma;i11
++
)
for
(
int
j11
=
0
;j11
<=
mb;j11
++
)
pre[ i11 ][ j11 ]
=
now[ i11 ][ j11 ];
}
int
max
=
0
;
for
(
int
i
=
0
;i
<=
ma;i
++
)
for
(
int
j
=
0
;j
<=
mb;j
++
) {
if
( now[ i ][ j ]
<
0
)
continue
;
int
t
=
i
*
d1
+
j
*
d2
+
now[ i ][ j ]
*
d3;
int
a
=
i
/
c1;
int
b
=
j
/
c2;
int
c
=
now[ i ][ j ]
/
c3;
if
( a
>
b ) a
=
b;
if
( a
>
c ) a
=
c;
if
( d4
>
0
) t
+=
a
*
d4;
if
( t
>
max ) max
=
t;
}
if
( cases
>
1
) cout
<<
endl;
cout
<<
"
Case
"
<<
cases
<<
"
:
"
<<
max
<<
endl;
}
return
0
;
}