2020-05-22

所有背包问题实现的例子都是下面这张图

01背包实现之——穷举法:

1.我的难点:

(1)在用穷举法实现代码的时候,我自己做的时候认为最难的就是怎么将那么多种情况表示出来,一开开始想用for循环进行多次嵌套,但是太麻烦,而且还需要不断的进行各种标记。我现在的水平实在太菜,然后就在一篇博文中看到一个特别巧妙的枚举算法,如下所示:

int fun(int x[n])

{

int i;

for(i=0;i

if(x[i]!=1) {x[i]=1; return;}

//从遇到的第一位开始,若是0,将其变成1,然后结束for循环,得到一种解法

else x[i]=0;

return;

//从第一位开始,若是1,将其变成0,然后继续循环,若再循环的时候遇到0,则将其变为1,结束循环。得到另一种解法。

}

虽然我现在也不知道为什么会这样,但是确实是个很好的规律,找到这个规律后,就可以很轻松的自己写出各种排列情况,以后遇到排列的问题,就用这个方法。语言不好描述,上图片演示(是歪的,凑活看吧。。。):

(2)算法思想:

x[i]的值为0/1,即选或者不选

w[i]的值表示商品i的重量

v[i]的值表示商品的价值

所以这个算法最核心的公式就是

tw=x[1]*w[1]+x[2]*w[2]+.......+x[n]*w[n]

tv=x[1]*w[1]+x[2]*v[2]+......+x[n]*v[n]

tv1:用于存储当前最优解

limit:背包容量

如果 twtv1 则可以找到最优解

2.代码实现(借鉴博文)

#include

#include

using namespace std;

#define n 4

void possible_solution(int x[n]){

int i;

for(i=0;i<4;i++) //n=4,有2^4-1种解法

if(x[i]!=1)

{

x[i]=1;

return; //从遇到的第一位开始,若是0,将其变成1,然后结束循环,得到一种解法

}

else

x[i]=0;

return;//从第一位开始,若是1,将其变成0,然后继续循环,若再循环的时候遇到0,则将其变为1,结束循环。得到另一种解法。

}

int main(){

int count=0;

int w[n]={2,3,4,5},v[n]={3,4,5,6};

int x[n]={0,0,0,0},y[n]={0,0,0,0};

int tw,tv,tv1=0,limit=8;

int j;

for(j=1;j<=15;j++){

possible_solution(x);

count++;

for(int i=0;i<4;i++){

cout<

}

cout<

tw=x[0]*w[0]+x[1]*w[1]+x[2]*w[2]+x[3]*w[3];

tv=x[0]*v[0]+x[1]*v[1]+x[2]*v[2]+x[3]*v[3];

if(tw<=limit&&tv>tv1){

tv1=tv; y[0]=x[0];y[1]=x[1];y[2]=x[2],y[3]=x[3];

}

}

cout<

printf("其中0-1背包问题的最优解为: y=(%d,%d,%d,%d)\n",y[0],y[1],y[2],y[3]);

printf("总价值为:%d",tv1);

}

3.运行结果:

4.复杂度分析

n个物品的话,就有2^n-1种解,所以其时间复杂度为O(2^n)

01背包问题之——贪心算法:

1.算法思路:

取单位价值量最大的那个物品先装入背包。所以还算好实现,得到每一个物品的价值量之后,查找最大的价值量的坐标,判断这个坐标额物品体积是否小于背包的容量,若小于,则装入背包。否则,继续循环。

2.代码实现 法一:

将得到的每个物品的价值量进行排序,得到一个递减序列。

#include

#include

#define n 4 //物品数列

#define c 8 //背包容量

using namespace std;

int w[4]={2.0,3.0,4.0,5.0};

float v[4]={3.0,4.0,5.0,6.0};

float sortBest[4]; //v[i]/w[i]

int C(){

for(int i=0;i<4;i++){

sortBest[i]=v[i]/w[i];

//cout<

}

cout<

}

int Sort(){

for(int i=0;i<4;i++)

{

int temp;

int wtemp;

int vtemp;

if(sortBest[i+1]>sortBest[i])

{

temp=sortBest[i];

sortBest[i]=sortBest[i+1];

sortBest[i+1]=temp;

wtemp=w[i];

w[i]=w[i+1];

w[i+1]=wtemp;

vtemp=v[i];

v[i]=v[i+1];

v[i+1]=vtemp;

}

//用来查看排序是否正确

cout<

cout<

cout<

cout<

cout<

}

cout<

}

int F(){

int c1=c;

int result=0;

for(int i=0;i<4;i++){

if(w[i]<=c1)

result=result+v[i];

c1=c1-w[i];

}

cout<

}

int main()

{

C();

cout<

Sort();

F();

return 0;

}

代码实现 法二:

没有对每个商品的价值量进行排序,直接查找当前价值量的最大值,判断其是否能够装入背包,若能,直接装入,令当前价值量为0,继续寻找第二大价值量,不断循环即可。代码如下:

#include

#include

#define n 4 //物品数列

#define c 8 //背包容量

using namespace std;

float w[4]={2.0,3.0,4.0,5.0};

float v[4]={3.0,4.0,5.0,6.0};

float sortBest[4]; //价值量 v[i]/w[i]

int C(){

for(int i=0;i<4;i++){

sortBest[i]=v[i]/w[i];

//cout<

}

}

int F()

{

float temp=0;

float result=0;

float c1=8; //用于改变c的值

for(int i=0;i<4;i++)

{

//for循环用来得到最大sortBest

for(i=0;i<4;i++)

{

if(temp

temp=sortBest[i];

}

//cout<

for(i=0;i<4;i++)

{

if (temp==sortBest[i])

//cout<

sortBest[i]=0;

if (w[i]<=c1)

result=result+v[i];

c1=c1-w[i];

}

}

cout<

}

int main()

{

cout<

cout<

cout<

cout<

for(int i=0;i<4;i++)

{

cout<

cout<

cout<

cout<

}

C();

F();

return 0;

}

3.遇到的困难

就是,当得到的价值量的包含小数时,而且刚好就靠小数部分区分大小时(比如1.5 ,1.33,)。c++正常输出的结果都是整数。

解决办法就是,将每个物品的价值量(3.0,4.0)和背包重量(2.0,3.0)都变float类型,注意定义的时候,也需要定义为float类型

4.复杂度:

时间复杂度:O(n)

01背包问题之——动态规划

1.算法思想

最重要的就是寻找递推关系式:

定义V[i,j]:当背包容量为j时,前i个物品最佳组合对应的值。

递推关系:

(1)当背包的容量不允许装入第i件物品时,和前一个物品装入背包一样。即 :V[i][j]=V[i-1][j]

(2)当背包的容积可以装入第i件物品时,分两种情况,A装入第i件物品不是最优,还不如不装。B装入第i件物品是最优。即:V[i][j]=max(V[i-1][j],V[i][j-w[i]]+v[i])

2.代码实现:

#include

using namespace std;

int w[5]={0,2,3,4,5};

int v[5]={0,3,4,5,6};

int V[5][9];

int c=8;

int B()

{

int i,j;

for(i=0;i<5;i++)

{

V[i][0]=0;

for(j=0;j

{

V[0][j]=0;

if(j

V[i][j]=V[i-1][j];

else

V[i][j]=max(V[i-1][j],V[i-1][j-w[i]]+v[i]);

}

}

}

int main(){

B();

//显示填好的表格

for (int i=0;i<5;i++)

{

for(int j=0;j<9;j++)

{

cout<

}

cout<

}

cout<

return 0;

}

下面是带上回溯找出解的组成的代码:

#include

using namespace std;

int w[5]={0,2,3,4,5};

int v[5]={0,3,4,5,6};

int V[5][9];

int c=8;

int item[4];

int B()

{

int i,j;

for(i=0;i<5;i++)

{

V[i][0]=0;

for(j=0;j

{

V[0][j]=0;

if(j

V[i][j]=V[i-1][j];

else

V[i][j]=max(V[i-1][j],V[i-1][j-w[i]]+v[i]);

}

}

}

void FindWhat(int i,int j)//寻找解的组成方式

{

if(i>=0)

{

if(V[i][j]==V[i-1][j])//相等说明没装

{

item[i]=0;//全局变量,标记未被选中

FindWhat(i-1,j);

}

else if( j-w[i]>=0 && V[i][j]==V[i-1][j-w[i]]+v[i] )

{

item[i]=1;//标记已被选中

FindWhat(i-1,j-w[i]);//回到装包之前的位置

}

}

}

int main(){

B();

//显示填好的表格

cout<

for (int i=0;i<5;i++)

{

for(int j=0;j<9;j++)

{

cout<

}

cout<

}

cout<

FindWhat(4,8);

cout<

cout<

for(int i=1;i<5;i++){

if(item[i]==1)

cout<

//cout<

}

return 0;

}

3.复杂度

时间复杂度:

O(物体个数*背包容积)=O(number*capacity)

空间复杂度:

用二维表实现的,所以和时间复杂度一样。

O(物体个数*背包容积)=O(number*capacity)

01背包之——递归

1.

递归法思路很单一,也是在递归方程的基础上,将其改造为可以递归的方式

2.代码演示

#include

using namespace std;

int n=4;

int w[4]={2,3,4,5};

int v[4]={3,4,5,6};

int y[4]={0,0,0,0};

int c=8;

int f(int n,int c)

{

int temp1;

int temp2;

if(n==0||c==0) {

return 0;}

else

{

for(int i=n-1;i>=0;i--)

{

if(w[i]>c)

{

return f(n-1,c);

}

else

{

temp1=f(n-1,c);

temp2=f(n-1,c-w[i])+v[i];

if(temp1>temp2)

{

return temp1;

}

else if(temp1

{

return temp2;

}

}

}

}

}

int main()

{

cout<

return 0;

}

3.我的难点:

因为是递归,所以其最大的缺点就是重复计算,所以如果我想查找他的解是什么,不容易查找。因为如果你进行标记的话,因为会重复计算,所以标记的话,标记也是不停的会变。所以我也不知道怎么解决。

4.复杂度:

O(2^n)

01背包之——回溯

java递归实现汉字组词穷举_01背包各种算法代码实现总结(穷举,贪心,动态,递归,回溯,分支限界)...相关推荐

  1. Python番外篇:网络爬虫组词程序

    今天,双是番外篇,这次番外篇主要教大家如何用网络爬虫查询词语. 1.确定数据源 首先,我们得找一个查询的数据源,我找到了360国学网站,选择"词语大全",它的查询词语网址为: ht ...

  2. java克鲁斯卡尔算法_Java语言基于无向有权图实现克鲁斯卡尔算法代码示例

    所谓有权图,就是图中的每一条边上都会有相应的一个或一组值.通常情况下,这个值只是一个数字 如:在交通运输网中,边上的权值可能表示的是路程,也可能表示的是运输费用(显然二者都是数字).不过,边上的权值也 ...

  3. 汉字 计算机 坟墓,墓的拼音_墓组词_墓意思(解释)-常用汉字大全

    墓的拼音,组词,意思(解释) 分类: 时间:2020年06月14日 1:35:28 本文主要介绍汉字「墓」的拼音,意思.解释,怎么组词,笔顺,笔画,部首等信息.仔细阅读,能够提高您文学修养. 「墓」拼 ...

  4. 括号配对检测python123_括的拼音_括组词_括意思(解释)-常用汉字大全

    括的拼音,组词,意思(解释) 分类: 时间:2020年06月16日 3:49:10 本文主要介绍汉字「括」的拼音,意思.解释,怎么组词,笔顺,笔画,部首等信息.仔细阅读,能够提高您文学修养. 「括」拼 ...

  5. 云速汉字、组词、拼音、造句、用法、音标采集软件

    云速针对汉字的拼音.组词.以及造句.用法.出处简单的写了一个采集软件,本软件需要用代理ip 因为目标站进行了防采集功能,只能换IP 进行采集,下面是软件截图 右边输入关键词然后在目标站进行采集,如果是 ...

  6. 穷人python入门教程视频_《穷》字意思读音、组词解释及笔画数 - 新华字典 - 911查询...

    基本词义 ◎ 穷 窮 qióng 〈形〉 (1) (形声.从穴,躬声.躬,身体,身在穴下,很窘困.简化字为会意,力在穴下,有劲使不出.本义:穷尽,完结) (2) 同本义 [end:limit] 穷,极 ...

  7. 三包围结构的字是什么样的_拼音带kun的字大全_50个拼音含kun的字组词

    原标题:拼音带kun的字大全_50个拼音含kun的字组词 1.昆(kūn),8画,上下结构,部首:曰(日) 组词:昆虫(kūn chóng) | 昆曲(kūn qǔ) | 昆山(kūn shān) | ...

  8. 扎的多音字组词有哪些

    "扎" 字共有 3 个读音:  [zhā]  [zhǎ]  [zhá] 读音为[zhā] 扎的多音字怎么组词 汉字 扎 拼音 zhā 解释 缠束.綑绑.同「紮」.书信.函件.同「札 ...

  9. Java 数字转汉字工具类

    Java 数字转汉字工具类 一.工具类--NumberToCnUtil package com.example.demotest.util;import java.util.Arrays; impor ...

最新文章

  1. .net中用css控制GridView样式
  2. html二级导航栏随一级居中,html – 1.在css中链接不起作用2.如何垂直居中导航栏并在每个导航栏上添加填充...
  3. 互联网1分钟 |1229
  4. python自动发微信-python实现微信每日一句自动发送给喜欢的人
  5. 8屏 旌宇多屏管理软件_如何选择拼接屏,不能说的秘密,都在这!
  6. 工作64:element多选功能
  7. c++基础学习(11)--(模板、预处理器、信号处理)
  8. long类型python_Python类型long vs C'long long'
  9. sql case when then else多个条件_SQL-多表查询
  10. Postman系列之安装及简介
  11. 利用Python分析航空公司客户价值
  12. Atitit.加密算法 des  aes 各个语言不同的原理与解决方案java php c#
  13. 互联网公司的规律.txt
  14. RNA-seq——五、根据差异基因画火山图、在火山图上标记基因名
  15. 【钢结构·技术】国内经典的钢结构建筑BIM应用
  16. 使用python实现多个excel文件合并到一个excel的不同sheet中
  17. 什么叫冷备用状态_线路和设备冷备用和热备用的状态分别是什么意思?
  18. spleeter音乐人声分离、5种架子鼓钢琴声音分离的高质量模型运行超详细教程windows+ubuntu18.04
  19. python爬虫毕业论文大纲参考模板_毕业论文大纲(目录)模板
  20. 模式窗口window.showModalDialog()的用法

热门文章

  1. MODBUS功能码15测试报文
  2. Lattice ECP5UM5G 踩过的坑
  3. 计算机科学与技术师范ppt,计科学院开展科普课件PPT评比会议
  4. Java字符串:valueOf() 方法
  5. TP FP TN FN
  6. 项目管理 王如龙老师 经典语录
  7. 【Android 10 源码】深入理解 software Codec2 服务启动
  8. 用声音检测技术降低美国“赌城”枪击案伤亡(paper+github)
  9. 图像去噪之 Noise2Noise 和 Noise2Void
  10. 树莓派驱动L9110H灭火风扇模块