Chinaunix首页 | 论坛 | 博客
  • 博客访问: 738385
  • 博文数量: 251
  • 博客积分: 10367
  • 博客等级: 上将
  • 技术积分: 2750
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-10 14:43
文章分类

全部博文(251)

文章存档

2009年(2)

2008年(86)

2007年(163)

分类: C/C++

2007-11-29 20:38:47

/*
  Name: 背包问题
  Date: 29-11-07 20:30
  Description: 采用的方法为动态规划,参考<算法设计技巧与分析>
  该方法只能输出一个结果,并且有些细节有待改进.
  测试:
  ***************knapstack.txt**************
  4 9
  ab
  2 3
  cd
  3 4
  ef
  4 5
  gh
 5 7
 ******************************************
 结果:
  *************knapstack_re.txt*************
  ab
  2 3
  cd
  3 4
  ef
  4 5
  *****************************************
*/


#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

#define MAX 60
const char* INPUT_FILE = "knapstack.txt";
const char* OUTPUT_FILE = "knapstack_re.txt";

char name[MAX][MAX]; //存储物品名

int    s[MAX]; //存储物品体积

int    v[MAX]; //存储物品价值

int    u[MAX][MAX]; //一个用来模仿递归的矩阵.

int    b[MAX][MAX]; //1:选择了u[i-1] 2:没选择u[i-1]


FILE *in,*out;

void knapstack(int n,int sum);
void print_knapstack();

//背包算法.

void knapstack(int n,int sum)
{
    int i,j;
    
    for(i = 0;i <= n;i ++)
        u[i][0] = 0;
    for(j = 0; j <= sum ; j ++)
        u[0][j] = 0;

    for(i = 1; i <= n; i ++)
        for(j = 1;j <= sum ;j ++)
        {
            u[i][j] = u[i-1][j];
            b[i][j] = 1;
            if(s[i-1] <= j && u[i-1][j-s[i-1]] + v[i-1] > u[i][j])
            {
                u[i][j] = u[i-1][j-s[i-1]] + v[i-1];
                b[i][j] = 2;
            }
        }
/*调试用
    for(i = 0;i <=n;i++)
    {
        for(j = 0;j <=sum;j ++)
            printf("%d ",u[i][j]);
         printf("\n");
        }

      for(i = 0;i <=n;i++)
    {
         for(j = 0;j <=sum;j ++)
              printf("%d ",b[i][j]);
         printf("\n");
       }
*/

}

//打印结果

void print_knapstack(int n,int sum)
{
    if(n == 0 || sum < 0)
        return;
    if(b[n][sum] == 2)
    {
        print_knapstack(n-1,sum - s[n-1]);
//        printf("%d %d\n",n,sum-s[n-1]);

        fputs(name[n-1],out);
        fprintf(out,"%d %d\n",s[n-1],v[n-1]);
    }
    else
    {
        print_knapstack(n-1,sum);
//        printf("%d %d\n",n,sum);

    }
        
}

int main()
{
    int i,j,num,sum;
    
    if((in = fopen(INPUT_FILE,"r")) == NULL || (out = fopen(OUTPUT_FILE,"w")) == NULL)
    {
           printf("Can't open the file.");
           getch();
     return 1;
    }
    fscanf(in,"%d %d ",&num,&sum); //num:物品数量 sum:总共能装下的体积


    for(i = 0;i < num ;i ++)
    {
    fgets(name[i],MAX,in);
    fscanf(in,"%d %d ",&s[i],&v[i]); //s[i]:第i个物品的体积,v[i]: 第i个物品的价值

    }
/*调试
    for(i =0;i     {
       printf("%s%d %d\n",name[i],s[i],v[i]);
    }
*/

    knapstack(num,sum);
    
    print_knapstack(num,sum);

    fclose(in);
    fclose(out);

    return 0;
}

阅读(1030) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~