问题描述:

给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为C。问:应该如何选择装入背包的物品,是的装入背包中物品的总价值最大?

细节须知:

暂无。

算法原理:

a.最优子结构性质

0-1背包问题具有最优子结构性质。设(y1,y2,…,yn)是所给0-1背包问题的一个最优解,则(y2,…,yn)是下面相应子问题的一个最优解。

b.递归关系

设所给0-1背包问题的子问题

的最优值为m(i,j),即m(i,j)是背包容量为j,可选择物品为i,i+1,…,n时0-1背包问题的最优值。有0-1背包问题的最优子结构性质,可以建立如下计算m(i,j)的递归式

 #include <iostream>
#include <fstream>
#include <ctime>
#include <algorithm>
#include <windows.h>
using namespace std;
#define N 10000 //int w[5] = { 0 , 2 , 3 , 4 , 5 }; //商品的体积2、3、4、5
//int v[5] = { 0 , 3 , 4 , 5 , 6 }; //商品的价值3、4、5、6
//int bagV = 8; //背包大小
int dp[N][N]; //动态规划表
//int item[5]; //最优解情况 void findMax(int k,int n,int w[],int v[]) { //动态规划
for (int i = ; i <= k; i++) {
for (int j = ; j <= n; j++) {
if (j < w[i])
dp[i][j] = dp[i - ][j];
else
dp[i][j] = max(dp[i - ][j], dp[i - ][j - w[i]] + v[i]);
}
}
} void findWhat(int i, int j,int w[],int v[],int item[]) { //最优解情况
if (i > ) {
if (dp[i][j] == dp[i - ][j]) {
item[i] = ;
findWhat(i - , j,w,v,item);
}
else if (j - w[i] >= && dp[i][j] == dp[i - ][j - w[i]] + v[i]) {
item[i] = ;
findWhat(i - , j - w[i],w,v,item);
}
}
} void print(int k,int n,int item[]) {
/*for (int i = 0; i < k+1; i++) { //动态规划表输出
for (int j = 0; j < n+1; j++) {
cout << dp[i][j] << ' ';
}
cout << endl;
}
cout << endl;*/
cout <<"The item number that should be put into the backpack is:";
for (int i = ; i < k+; i++){ //最优解输出
if(item[i] == )
cout << i << ' ';
}
cout << endl;
} int main(void)
{
LARGE_INTEGER nFreq;
LARGE_INTEGER nBeginTime;
LARGE_INTEGER nEndTime;
ofstream fout;
double cost;
int i,j,m,n,k;
cout << "Please enter the number of times you want to run the program:";
cin >> m;
//int object_amount[m];
//double runtime[m];
fout.open("backpack.txt",ios::app);
if(!fout){
cerr<<"Can not open file 'backpack.txt' "<<endl;
return -;
}
fout.setf(ios_base::fixed,ios_base::floatfield); //防止输出的数字使用科学计数法
srand((unsigned int)time(NULL));
for(i = ; i < m; i++){
n = rand()%;
k = rand()%;
//object_amount[i] = k;
fout<<k<<",";
int item[k];
cout << "The " << i+ << "th test's backpack lattice number is:" << n << endl;
cout << "The " << i+ << "th test's object amount is:" << k << endl;
int w[k];
int v[k];
memset(dp,,sizeof(dp));
w[] = ;
v[] = ;
for(j=;j<k;j++){
w[j]=rand()%;
v[j]=rand()%;
}
QueryPerformanceFrequency(&nFreq);
QueryPerformanceCounter(&nBeginTime);
findMax(k,n,w,v);
findWhat(k,n,w,v,item);
print(k,n,item);
QueryPerformanceCounter(&nEndTime);
cost=(double)(nEndTime.QuadPart - nBeginTime.QuadPart) / (double)nFreq.QuadPart;
//runtime[i]=cost;
fout<<cost<<endl;
cout<<"The running time is:"<<cost<<" s"<<endl;
}
/* fout.open("backpack.txt",ios::app);
if(!fout){
cerr<<"Can not open file 'backpack.txt' "<<endl;
return -1;
}
fout.setf(ios_base::fixed,ios_base::floatfield); //防止输出的数字使用科学计数法
for(i=0;i<m;i++){
fout<<object_amount[i]<<","<<runtime[i]<<endl;
}*/
fout.close();
cout<<"Success!"<<endl;
return ;
}

程序设计思路:

根据算法原理中所述递归关系,递归计算全部的m(i,j),得到不同情况下的最优解。

假设m[1][c]给出所要求的的0-1背包问题的最优值。相应的最优解计算如下:

如果m[1][c]=m[2][c],则x1=0;否则x1=1.当x1=0是,由m[2][c]继续构造最优解;当x1=1时,有m[2][c-w1]继续构造最优解。以此类推,可构造出相应的最优解(x1,x2,…,xn)。

时间复杂性分析:

从计算m(i,j)的递归式容易看出,对于0-1背包问题的求解算法需要O(nc)计算时间,而算法解出最优方案需要O(n)计算时间,当背包容量c很大时,算法需要的计算时间较多。

生成的数据可导入EXCEL中进行数据分析生成分析图表。

C++动态规划求解0-1背包问题的更多相关文章

  1. Java实现动态规划法求解0/1背包问题

    摘要: 使用动态规划法求解0/1背包问题. 难度: 初级 0/1背包问题的动态规划法求解,前人之述备矣,这里所做的工作,不过是自己根据理解实现了一遍,主要目的还是锻炼思维和编程能力,同时,也是为了增进 ...

  2. hdu2602Bone Collector ——动态规划(0/1背包问题)

    Problem Description Many years ago , in Teddy’s hometown there was a man who was called “Bone Collec ...

  3. 背包问题(Knapsack problem)采用动态规划求解

    问题说明: 假设有一个背包的负重最多可达8公斤,而希望在背包中装入负重范围内可得之总价物品,假设是水果好了,水果的编号.单价与重量如下所示:0李子4KGNT$45001苹果5KGNT$57002橘子2 ...

  4. 0-1背包问题——动态规划求解【Python】

    动态规划求解0-1背包问题: 问题:背包大小 w,物品个数 n,每个物品的重量与价值分别对应 w[i] 与 v[i],求放入背包中物品的总价值最大. 动态规划核心:计算并存储小问题的最优解,并将这些最 ...

  5. 经典递归问题:0,1背包问题 kmp 用遗传算法来解背包问题,hash表,位图法搜索,最长公共子序列

    0,1背包问题:我写笔记风格就是想到哪里写哪里,有很多是旧的也没删除,代码内部可能有很多重复的东西,但是保证能运行出最后效果 '''学点高大上的遗传算法''' '''首先是Np问题的定义: npc:多 ...

  6. 蓝桥杯 0/1背包问题 (java)

      今天第一次接触了0/1背包问题,总结一下,方便以后修改.不对的地方还请大家不啬赐教! 上一个蓝桥杯的例题: 数据规模和约定 代码: import java.util.Scanner; public ...

  7. 动态规划 求解 Minimum Edit Distance

    http://blog.csdn.net/abcjennifer/article/details/7735272 自然语言处理(NLP)中,有一个基本问题就是求两个字符串的minimal Edit D ...

  8. 动态规划:HDU1059-Dividing(多重背包问题的二进制优化)

    Dividing Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  9. 动态规划求解序列问题(LIS、JLIS)

    1. 最长递增子序列 不要求位置连续:要求大小严格递增(strictly increasing) 穷举法解题 首先以每个数字为单位分割寻找最长递增子序列: int lis(const vector&l ...

随机推荐

  1. android studio学习----The project encoding (windows-1252) does not match the encoding specified in the Gradle build files (UTF-8)

    Warning:The project encoding (windows-1252) does not match the encoding specified in the Gradle buil ...

  2. Model 中的Meta类选项

    通过一个内嵌类 "class Meta" 给你的 model 定义元数据, 类似下面这样: class Foo(models.Model): bar = models.CharFi ...

  3. Odoo报表的report标签和报表格式定义

    转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10826329.html 一:Report标签     report标签可用于定义一条报表记录.属性有: 1) ...

  4. Linux常用指定

    学前理论 linux主要特征 :一切且文件(目录.硬盘等都是文件):硬件都在/dev 目录,如硬盘.U盘为/dev/sd[a-d]: /dev/sr0(/dev/cdrom)是光驱的设备名(df命令查 ...

  5. Nginx 核心配置-location的匹配案例实战篇

    Nginx 核心配置-location的匹配案例实战篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.location语法规则介绍 在没有使用正则表达式的时候,nginx会先在 ...

  6. JavaScript 关于金额、数字验证的正则表达式

    JavaScript 关于金额.数字验证的正则表达式 function ismoney(money) { var reg = /(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^ ...

  7. Samba应用案例

    一.配置文件详解 Samba配置文件非常简洁明了,所有的设置都在 /etc/samba/smb.conf 配置文件中进行,通过对该配置文件的修改,可以将Samba配置为一台匿名文件服务器.基于账户的文 ...

  8. oneinstack——证书更新

    如果你安装好 oneinstack 你的定时任务就会自动添加 "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh ...

  9. 【pytorch】持续踩坑 & 错误解决经历

    报错 1.[invalid argument 0: Sizes of tensors must match except in dimension 0.] {出现在 torch.utils.data. ...

  10. ABP JS调用接口 获取返回的数据

    var _userService = abp.services.app.user; console.log(abp.services.app.user); _userService.getUserBy ...