ChenGen

一切归零,重新开始
随笔 - 13, 文章 - 10, 评论 - 21, 引用 - 0
数据加载中……

复习动态规划算法——01背包问题

   今天复习了动态规划算法。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 <= &&  W[k] < ww) {
                W[next]
= W[k];
                P[next]
= P[k];
                next
++ ;
                k
++ ;
            }

            
if (k <= &&  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 <= &&  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);
}




posted on 2006-09-28 12:52 ChenGen 阅读(9873) 评论(3)  编辑  收藏 所属分类: 数据结构复习

评论

# re: 复习动态规划算法——01背包问题  回复  更多评论   

你根本是帖程序嘛……
都没有说说过程~
2007-08-09 14:43 | 郁闷……

# re: 复习动态规划算法——01背包问题[未登录]  回复  更多评论   

大哥不要贴程序啊
2008-03-31 11:58 | dd

# re: 复习动态规划算法——01背包问题[未登录]  回复  更多评论   

看不懂……一句注释也没有
int * f,l,h,k,next,u,i,j,pp,ww,m;
这么多又这么没有意义的变量……
看到就晕了……
2008-04-20 11:52 | vivi

只有注册用户登录后才能发表评论。


网站导航: