01背包问题
来源:互联网 发布:mysql修改端口 编辑:程序博客网 时间:2024/05/29 09:01
(DP)01背包问题
/*
* =====================================================================================
*
* Filename: Bag01.c
*
* Description: 01背包问题
* 有N个物品, 重量分别为w1到wn,价值分别为v1到vn,有一个承重为C的包,问该将哪些物品放入包
* 中可使得包中物品的价值和最大, 设m[i][j]代表在承重为j,可供装包的物品编号为从i(包括i)
* 到N时的最大价值(物品的最小编号为1),则此时递推公式为
* m[i][j] = max(m[i+1][j], m[i+1][j-wi] + vi) //两种情况:取物品i和不取物品i,从这两种情况中取最大值
* Version: 1.0
* Created: 2010年08月25日 08时59分40秒
* Revision: none
* Compiler: gcc
*
* Author: glq2000 (), glq2000@126.com
* Company: HUE ISRC
*
* =====================================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX(A,B) (((A)>(B))?(A):(B))
#define N 7 //物品个数
#define C 19 //包的承重
int w[N+1] = {0, 3, 7, 2, 4, 8, 10, 5}; //w[i]:物品i的重量, 简单起见,w[0]不使用
int v[N+1] = {0, 2, 10, 3, 5, 7, 12, 6};//v[i]:物品i的价值, 简单起见,v[0]不使用
int m[N+1][C+1];//加1的目的是为了使用方便,m[i][j]表示在承重为j,可供装包的物品编号为从i(包括i)到N时的最大价值(物品的最小编号为1)
void MaxBagValue(int (*m)[C+1], int n, int c, int *w, int *v); //计算m[i][j]数组
void Output(int (*m)[C+1]); //输出m[i][j]数组
void TraceBack(int (*m)[C+1]); //求出被选择的物品的编号
int main()
{
MaxBagValue(m, N, C, w, v);
Output(m); printf("\n\n\n\n");
printf("MaxBagValue: %d\n\n", m[1][C]);
TraceBack(m);
return 0;
}
/*
*m[i][j]表示在承重为j,可供装包的物品编号为从i(包括i)到N时的最大价值(物品的最小编号为1)
*w[i] 重量, v[i] 价值, c当前包中剩余承重, n 当前可供装包的编号为从n(包括n)到N
*/
void MaxBagValue(int (*m)[C+1], int n, int c, int *w, int *v)
{
int i, j;
for(j=1; j<=c; ++j)
if(j >= w[N])
m[N][j] = v[N];
for(i=n-1; i>=1; --i)
{
for(j=1; j<=c; ++j)
if(j >= w[i])
m[i][j] = MAX(m[i+1][j], m[i+1][j-w[i]]+v[i]);
else
m[i][j] = m[i+1][j];
}
}
void Output(int (*m)[C+1]) //输出m[i][j]数组
{
int i,j;
for(i=1; i<=N; ++i)
{
printf("w[%d]=%d ", i, w[i]);
}
printf("\n");
for(i=1; i<=N; ++i)
{
printf("v[%d]=%d ", i, v[i]);
}
printf("\n\n");
for(i=0; i<=N; ++i)
{
for(j=0; j<=C; ++j)
{
printf("m[%d][%d]=%d ", i, j, m[i][j]);
}
printf("\n\n");
}
}
//利用m数组求出哪些编号的物品被选中了
void TraceBack(int (*m)[C+1])
{
printf("Seletced: ");
int i=1,j=C;
while(j && i<=N)
{
if(i==N && j>0 && m[i][j]==v[i])
{
printf("%d ", i);
j -= w[i];
++i;
}
if(m[i][j] > m[i+1][j])
{
printf("%d ", i);
j -= w[i];
++i;
}
else
++i;
}
printf("\n");
}
* =====================================================================================
*
* Filename: Bag01.c
*
* Description: 01背包问题
* 有N个物品, 重量分别为w1到wn,价值分别为v1到vn,有一个承重为C的包,问该将哪些物品放入包
* 中可使得包中物品的价值和最大, 设m[i][j]代表在承重为j,可供装包的物品编号为从i(包括i)
* 到N时的最大价值(物品的最小编号为1),则此时递推公式为
* m[i][j] = max(m[i+1][j], m[i+1][j-wi] + vi) //两种情况:取物品i和不取物品i,从这两种情况中取最大值
* Version: 1.0
* Created: 2010年08月25日 08时59分40秒
* Revision: none
* Compiler: gcc
*
* Author: glq2000 (), glq2000@126.com
* Company: HUE ISRC
*
* =====================================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX(A,B) (((A)>(B))?(A):(B))
#define N 7 //物品个数
#define C 19 //包的承重
int w[N+1] = {0, 3, 7, 2, 4, 8, 10, 5}; //w[i]:物品i的重量, 简单起见,w[0]不使用
int v[N+1] = {0, 2, 10, 3, 5, 7, 12, 6};//v[i]:物品i的价值, 简单起见,v[0]不使用
int m[N+1][C+1];//加1的目的是为了使用方便,m[i][j]表示在承重为j,可供装包的物品编号为从i(包括i)到N时的最大价值(物品的最小编号为1)
void MaxBagValue(int (*m)[C+1], int n, int c, int *w, int *v); //计算m[i][j]数组
void Output(int (*m)[C+1]); //输出m[i][j]数组
void TraceBack(int (*m)[C+1]); //求出被选择的物品的编号
int main()
{
MaxBagValue(m, N, C, w, v);
Output(m); printf("\n\n\n\n");
printf("MaxBagValue: %d\n\n", m[1][C]);
TraceBack(m);
return 0;
}
/*
*m[i][j]表示在承重为j,可供装包的物品编号为从i(包括i)到N时的最大价值(物品的最小编号为1)
*w[i] 重量, v[i] 价值, c当前包中剩余承重, n 当前可供装包的编号为从n(包括n)到N
*/
void MaxBagValue(int (*m)[C+1], int n, int c, int *w, int *v)
{
int i, j;
for(j=1; j<=c; ++j)
if(j >= w[N])
m[N][j] = v[N];
for(i=n-1; i>=1; --i)
{
for(j=1; j<=c; ++j)
if(j >= w[i])
m[i][j] = MAX(m[i+1][j], m[i+1][j-w[i]]+v[i]);
else
m[i][j] = m[i+1][j];
}
}
void Output(int (*m)[C+1]) //输出m[i][j]数组
{
int i,j;
for(i=1; i<=N; ++i)
{
printf("w[%d]=%d ", i, w[i]);
}
printf("\n");
for(i=1; i<=N; ++i)
{
printf("v[%d]=%d ", i, v[i]);
}
printf("\n\n");
for(i=0; i<=N; ++i)
{
for(j=0; j<=C; ++j)
{
printf("m[%d][%d]=%d ", i, j, m[i][j]);
}
printf("\n\n");
}
}
//利用m数组求出哪些编号的物品被选中了
void TraceBack(int (*m)[C+1])
{
printf("Seletced: ");
int i=1,j=C;
while(j && i<=N)
{
if(i==N && j>0 && m[i][j]==v[i])
{
printf("%d ", i);
j -= w[i];
++i;
}
if(m[i][j] > m[i+1][j])
{
printf("%d ", i);
j -= w[i];
++i;
}
else
++i;
}
printf("\n");
}
- 背包问题---01背包
- DP 背包问题 01背包
- 01背包--苹果,背包问题
- 01背包 完全背包问题
- 背包问题之01背包
- 背包问题之01背包
- 背包问题1:01背包
- 背包问题《1》01背包
- 01背包+完全背包问题
- 背包问题-背包01-苹果
- 背包问题之01背包
- 背包问题(01背包,完全背包,多重背包)
- 背包问题(01背包,完全背包,多重背包)
- 动态规划-----背包问题-----01背包,完全背包,多重背包
- 经典背包问题 01背包+完全背包+多重背包
- 背包(01背包、完全背包、多重背包)问题总结
- 背包问题(01背包,完全背包,多重背包)
- 经典背包问题 01背包+完全背包+多重背包
- USACO Section 1.2 Name That Number
- 全选,反选,全不选代码
- 安卓自动化测试-脚本相关初探
- android Immutable bitmap passed to Canvas constructor异常
- 自动化脚本-TCL语言使用以及个人体会
- 01背包问题
- 变形课
- Topcoder SRM 505 Div 2 hard
- 面试题目2
- java.net.BindException: Address already in use: JVM_Bind
- [敏捷]项目管理工具redmine安装手册
- 移植IAR到 AVR GCC
- Web开发杂谈
- LT自动挡,ET手动挡(epoll)