动态规划求解0-1背包

C代码实现如下:


  1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int** DP(int num, int Weight, int*w, int *v);
5 void output(int *c, int *w, int weight, int **ptr, int num);
6 int main()
7 {
8
9
10 int w[] = {3, 4, 7, 8, 9};
11 int v[] = {4, 5, 10, 11, 13};
12 int num = 5, weight = 17;
13 int out[5] = {0};
14 int i = 0, j = 0;
15 int **ptr = NULL;
16
17 ptr = DP(num, weight, w, v);
18 output(out, w, weight, ptr, num);
19
20 for(i = 0; i< num; i++)
21 {
22 for(j = 0; j < weight + 1; j++)
23 {
24 printf("%2d ", ptr[i][j]);
25 }
26 printf("\n");
27 free(ptr[i]);
28 ptr[i] = NULL;
29 }
30 printf("\n");
31 free(ptr);
32 ptr = NULL;
33
34 for(i = 0; i < num; i++)
35 {
36 printf("%d ", out[i]);
37 }
38 printf("\n");
39 system("pause");
40 return 0;
41 }
42
43
44 int** DP(int num, int Weight, int*w, int *v)
45 {
46 int **arr = (int**)calloc(num, sizeof(int*));
47 int i = 0, j = 0;
48 for(i = 0; i < num; i++)
49 {
50 arr[i] = (int*)calloc(Weight + 1, sizeof(int));
51 }
52
53 for(i = 0; i < Weight + 1; i++)
54 {
55 arr[0][i] = 0;
56 }
57 for(i = 0; i < num; i++)
58 {
59 arr[i][0] = 0;
60 for(j = 0; j < Weight + 1; j++)
61 {
62 if(w[i] <= j)
63 {
64 if(i == 0)
65 {
66 arr[i][j] = v[i];
67 }
68 else
69 {
70 if(v[i] + arr[i - 1][j - w[i]] >= arr[i - 1][j])
71 {
72 arr[i][j] = v[i] + arr[i-1][j- w[i]];
73 }
74 else
75 {
76 arr[i][j] = arr[i - 1][j];
77 }
78 }
79 }
80 else
81 {
82 if(i == 0)
83 {
84 arr[i][j] = 0;
85 }
86 else
87 {
88 arr[i][j] = arr[i - 1][j];
89 }
90
91 }
92
93 }
94 }
95
96 return arr;
97 }
98
99 void output(int *c, int *w, int weight, int **ptr, int num)
100 {
101 int i = 0;
102
103 for(i = num - 1; i >=1; i--)
104 {
105 if(ptr[i][weight] == ptr[i - 1][weight])
106 {
107 c[i] = 0;
108 }
109 else
110 {
111 c[i] = 1;
112 weight -= w[i];
113 }
114
115
116 }
117
118 if(ptr[i][weight] == 0)
119 {
120 c[i] = 0;
121 }
122 else
123 {
124 c[i] = 1;
125 }
126
127 }

时间: 2024-11-05 17:29:42

动态规划求解0-1背包的相关文章

动态规划算法求解0,1背包问题

首先我们来看看动态规划的四个步骤: 1. 找出最优解的性质,并且刻画其结构特性: 2. 递归的定义最优解: 3. 以自底向上的方式刻画最优值: 4. 根据计算最优值时候得到的信息,构造最优解 其中改进的动态规划算法:备忘录法,是以自顶向下的方式刻画最优值,对于动态规划方法和备忘录方法,两者的使用情况如下: 一般来讲,当一个问题的所有子问题都至少要解一次时,使用动态规划算法比使用备忘录方法好.此时,动态规划算法没有任何多余的计算.同时,对于许多问题,常常可以利用其规则的表格存取方式,减少动态规划算

动态规划求解0-1背包问题

0-1背包问题是: 一个背包能承受的最大容量为max_weight,  现在有n个物品, 它们的重量分别是{w1,w2,w3,......wn}, 和价值分别是{v1,v2,......vn}, 现在要求在满足背包装载的物品不超过最大容量的前提下,保证装载的物品的价值最大? 动态规划求解过程可以这样理解: 对于前i件物品,背包剩余容量为j时,所取得的最大价值(此时称为状态3)只依赖于两个状态. 状态1:前i-1件物品,背包剩余容量为j.在该状态下,只要不选第i个物品,就可以转换到状态3. 状态2

1008-----算法笔记----------0-1背包问题(动态规划求解)

1.问题描述 给定n种物品和一个背包,物品i的重量是wi,其价值为vi,背包的容量为C.问:应该如何选择装入背包的物品,使得装入背包中物品的总价值最大? 2.问题分析 上述问题可以抽象为一个整数规划问题,即求满足 (a)Σwixi ≤ C:(b)xi ∈(0,1),  1≤i≤n:条件下,∑vixi最大时的一个物品xi序列.分析问题可以发现,该问题具有最优子结构性质,那么就可以尝试用动态规划方法求解,而动态规划求解的关键就是列出问题的递归关系表达式. 设m(i,j)为背包容量为j,可选物品为i,

基础算法(七)——动态规划【0/1背包问题】

首先,对于动态规划,我来做一个简短的介绍,相信各位都看得懂.动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法.先给一道最简单的例题(小学奥数水平): 这就是一个模拟的动态规划法! 好了,现在开始认识一下最简单的动态规划实例:0/1背包. [问题描述]有一位旅行者要出远门,到商店里去筹备东西.在商店里,摆放了n样物品,每种物品有各自的体积,但是每种物品只有一件.这个旅行家有一个限制装V个体积的物品的背包,但是这

求解0/1背包问题

动态规划 //求解0_1背包问题 //动态规划 #include<stdio.h> #define MaxN 20 #define MaxW 100 int knap(int f[MaxN][MaxW],int w[],int v[],int W,int n){ //动态规划求数组f[][] int i,r; for(i=0;i<=n;i++) f[i][0] = 0; for(r=0;r<=W;r++) f[0][r] = 0; for(i=1;i<=n;i++){ for

动态规划求解最长公共子序列

动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解.与分治法不同的是,适合于用动态规划求解的问题,经分解得到的子问题往往不是互相独立的.若用分治法来解决这类问题,则分解得到的子问题数目太多,以至于最后解决原问题需要耗费指数时间.然而,不同子问题的数目常常只有多项式量级.在用分治法求解时,有些子问题被重复计算了许多次.如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,从而得到多项式

动态规划求解最大字段和及其变种问题

动态规划(Dynamic Programming, DP)为一常用算法思想,本文讲述如何利用DP解决常见的最大字段和及其变种问题. 一. 最大字段和问题 问题定义 设数组为a[k],1≤k≤n,最大字段和X定义为: X=max1≤i≤j≤n{∑k=ija[k]} X直观含义即,求任一连续字数组的最大和. 问题分析 不妨设: b[j]=max1≤m≤j{∑k=mja[k]} 其中,1≤j≤n b[j]的直观含义为,以a[j]为结束元素的连续数组的最大和. 由X和b[j]的定义,易知: X=max1

动态规划求解所有字符的组合数

一,问题描述 给定若干个字符,求解 这些字符能够表示的最多组合个数.比如{'a','b','c'} 一共有七种组合.(每种组合没有重复的字符 且 组合的种数与顺序无关,如 ab 和 ba 是同一种组合) a.b .c .ab .ac .bc .abc 其实,求组合个数,可以用公式来求解:具给定 n种字符,一共有  c(n,1)+c(n,2)+...+c(n,n)种不同的组合.其中,c(n,i)表示:从n个字符中任选 i 个的组合数,数学表示为:C in. 二,DP算法思路 既然已经可以用上面的公

【算法导论之七】动态规划求解最长公共子序列

一.动态规划的概念 动态规划(Dynamic Programming)是通过组合子问题的解而解决整个问题的.分治算法是指将问题划分成一些独立的子问题,递归地求解各子问题,然后合并子问题的解而得到原始问题的解,与此不同,动态规划适用于子问题不是独立的情况,也就是各个子问题包含公共的子问题.在这种情况下,采用分治法会做许多不必要的工作,即重复地求解公共地子问题.动态规划算法对每个子问题只求解一次,将其结果保存在一张表中,从而避免每次遇到各个子问题时重新计算答案. 动态规划通常应用于最优化问题.此类问

POJ 3628 Bookshelf 2 0/1背包和DFS两种解法

题目链接:POJ 3628 Bookshelf 2 Bookshelf 2 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7462   Accepted: 3436 Description Farmer John recently bought another bookshelf for the cow library, but the shelf is getting filled up quite quickly,