Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1413992
  • 博文数量: 241
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 2253
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-11 22:27
个人简介

--

文章分类

全部博文(241)

文章存档

2021年(3)

2019年(6)

2018年(1)

2017年(9)

2016年(21)

2015年(50)

2014年(125)

2013年(26)

我的朋友

分类: C/C++

2014-04-12 17:22:33

1、题目描述
 有N种物品,第i种物品的重量为wi,价值为vi,每种物品只有一个。背包能承受的重量为W。将哪些物品装入背包可使这些物品的总重量不超过背包容量,且价值总和最大?

输入:
第1行包含一个整数T,表示有T组测试用例。每组测试用例有3行,第1行包含两个整数
N; W(N1000; W 1000)分别表示物品的种数和背包的容量,第2行包含N个整数表示每种物
品的价值,第3行包含N个整数表示每种物品的重量。
输出:
每行一个整数,表示价值总和的最大值

举例:
输入--》1 
           5 10
           1 2 3 4 5
           5 4 3 2 1
输出--》14

2、分析:
每件物品均只有一件,可以选择装或者不装。
定义状态f[i][j],表示“前i个物品装进容量为j的背包可以获取最大 的价值”
状态方程:f[i][j] = max{ f[i-1][j], f[i-1][j-w[i]] + v[i]}

3、代码

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <string.h>
  3. #define MAXN 1000
  4. #define MAXW 1000
  5. int N, W;
  6. int w[MAXN+1], v[MAXN+1]; /* 0 没有用*/
  7. int f[MAXN + 1][MAXW + 1];
  8. void dp() {
  9.   int i, j;
  10.   memset(f, 0, sizeof(f)); /*背包不一定要装满*/
  11.   for(i = 1; i <= N; ++i) {
  12.    for(j = 0; j <= W; ++j) {
  13.      f[i][j] = f[i-1][j];
  14.      if(j >= w[i]) {
  15.       const int tmp = f[i-1][j-w[i]] + v[i];
  16.       if(tmp > f[i][j]) f[i][j] = tmp;
  17.      }
  18.    }
  19.  }
  20. }
  21. int main() {
  22.  int i, T;
  23.  scanf("%d", &T);
  24.  while(T--) {
  25.  scanf("%d %d", &N, &W);
  26.  for(i = 1; i <= N; ++i) scanf("%d", &v[i]);
  27.  for(i = 1; i <= W; ++i) scanf("%d", &w[i]);
  28.  dp();
  29.  printf("%d\n", f[N][W]);
  30.  }
  31.  return 0;
  32. }
阅读(828) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~