|
今天复习了动态规划算法。01背包问题是一个典型的动态规划问题。算法的证明过程比较复杂,但是计算过程并不难理解。 假设有这样的序列 n=3 M=6 (物体数量为3,背包能背的重量为6) wi 2 3 4 (物体重量) pi 1 2 5 (物体的价值)
初始化:Si={(P)}(待完成)
代码:
#include
"
stdio.h
"
#include
"
stdlib.h
"
#define MAXSIZE
1000
void
DKNAP(
int
*
,
int
*
,
int
,
int
);
void
PARTS(
int
*
,
int
*
,
int
*
,
int
*
,
int
,
int
);

void
main(
void
)

{
int
i,j,n,
*
w,
*
p,M;

if
(freopen(
"
input.txt
"
,
"
r
"
,stdin)
==
NULL)
{
printf(
"
can't open file 'input.txt'\n
"
);
exit(
-
1
);
}
scanf(
"
%d
"
,
&
n);
scanf(
"
%d
"
,
&
M);
w
=
(
int
*
)malloc(sizeof(
int
)
*
n);
p
=
(
int
*
)malloc(sizeof(
int
)
*
n);
for
(i
=
0
;i
<
n;i
++
)
scanf(
"
%d
"
,
&
w[i]);
for
(i
=
0
;i
<
n;i
++
)
scanf(
"
%d
"
,
&
p[i]);
DKNAP(w,p,n,M);
}
void
DKNAP(
int
*
w,
int
*
p,
int
n,
int
M)

{
int
*
f,l,h,k,next,u,i,j,pp,ww,m;
int
P[MAXSIZE],W[MAXSIZE];
f
=
(
int
*
)malloc(sizeof(
int
)
*
(n
+
1
));
P[
0
]
=
0
;
W[
0
]
=
0
;
f[
0
]
=
next
=
1
;
l
=
h
=
0
;

for
(i
=
0
;i
<
n;i
++
)
{
k
=
l;
j
=
h;
while
(W[j]
+
w[i]
>
M) j
--
;
u
=
j;

for
(j
=
l;j
<=
u;j
++
)
{
ww
=
W[j]
+
w[i];
pp
=
P[j]
+
p[i];

while
(k
<=
h
&&
W[k]
<
ww)
{
W[next]
=
W[k];
P[next]
=
P[k];
next
++
;
k
++
;
}
if
(k
<=
h
&&
W[k]
==
ww)
{
pp
=
pp
>
P[k]
?
pp:P[k];
k
++
;
}
if
(pp
>
P[next
-
1
])
{
P[next]
=
pp;
W[next]
=
ww;
next
++
;
}
while
(k
<=
h
&&
P[k]
<
P[next
-
1
] ) k
++
;
}
while
(k
<=
h)
{
P[next]
=
P[k];
W[next]
=
W[k];
next
++
;
k
++
;
}
f[i
+
1
]
=
next;
l
=
h
+
1
;
h
=
next
-
1
;

}
m
=
W[next
-
1
];
printf(
"
\np max is %d \n
"
,P[next
-
1
]);
PARTS(W,w,p,f,n
-
1
,m);
}
void
PARTS(
int
*
W,
int
*
w,
int
*
p,
int
*
f,
int
i,
int
m)

{
int
flag,j,k;

while
(m
>
0
&&
i
>
0
)
{
flag
=
0
;
for
(j
=
f[i
-
1
];j
<
f[i];j
++
)

if
(W[j]
==
m)
{
flag
=
1
;
break
;
}
if
(flag
==
0
)
{
printf(
"
%d\n
"
,i);
m
-=
w[i];
}
i
--
;
}
if
(m
>
0
) printf(
"
%d\n
"
,i);
}
|