动态规划(冬令营课堂笔记)

简单问题

  01背包

  012背包

  部分背包

  机器分配

  烽火传递

  花店橱窗问题

简单问题

01背包

一个容量为m的背包,有n个物品,第i个物品的体积为wi,价值为ci。选择若干物品,使得体积总和不超过m的情况下价值总和最大。

n<=100,m<=10000。

 

搜索  复杂度为2^n

void dfs(int x,int y,int z)//当前物品编号,当前容量,当前价值
{if(x==n+1){if(y<m)ans=max(ans,z);return;}dfs(x+1,y+w[x],z+c[i]);dfs(x+1,y,z);
}

如果前两维相同,只需选择第三维的最大值

小小的变形

const int INF=0x7f;
int dfs(int x,int y)
{int ans;if(x==n+1){if(y>m)return -INF;return 0;}ans=max(dfs(x+1,y+w[x])+c[x],dfs(x+1,y));return ans;
}
dfs(1,0);

加一个数组记录

const int INF=0x7f;
int dfs(int x,int y)
{if(x==n+1){if(y>m)return -INF;return 0;}dp[x][y]=max(dfs(x+1,y+w[x])+c[x],dfs(x+1,y));return dp[x][y];
}
dfs(1,0);

应用记录状态  记忆化搜索 n*m

const int INF=0x7f;
int dfs(int x,int y)
{if(y>m)return -INF;if(x==n+1){return 0;}if(dp[x+1][y+w[x]])             //选该物品 dp[x][y]=max(dp[x+1][y+w[x]]+c[x],dp[x][y]);elsedp[x][y]=max(dfs(x+1,y+w[x])+c[x],dp[x][y]); if(dp[x+1][y])             //不选该物品 dp[x][y]=max(dp[x+1][y]+c[x],dp[x][y]);elsedp[x][y]=max(dfs(x+1,y))+c[x],dp[x][y]);     return dp[x][y];
}
dfs(1,0);

递归变递推

先写出搜索

最大/最小值 存放到数组中

后面递归该状态时 直接使用数组中的值来代替

O(dfs里的状态个数*转移的时间复杂度)

 

找边界

找递推方法(顺序还是逆序)

转移(推转移方程)

搜索->记忆化搜索->递归变递推

for(int i=n;i>=1;i--)for(int j=0;j<=m;j++)dp[i][j]=max(dp[i+1][j],dp[i+1][j+w[i]]+c[i]);
ans=dp[1][0]

012背包

一个容量为m的背包,有n个物品,第i个物品的体积为wi,价值为ci,有2个。

选择若干物品,使得体积总和不超过m的情况下价值总和最大。

记忆化搜索

const int INF=0x7f;
int dfs(int x,int y,int z)
{if(x==n+1){if(y<m)ans=max(ans,z);return -INF;}if(dp[x+1][y])                    //一个都不选 dp[x][y]=max(dp[x][y],dp[x+1][y]);elsedp[x][y]=max(dp[x][y],dfs(x+1,y));if(dp[x+1][y+w[x]])                //选一个 dp[x][y]=max(dp[x][y],dp[x+1][y+w[x]])+c[x]);elsedp[x][y]=max(dp[x][y],dfs(x+1,y+w[x])+c[x]);if(dp[x+1][y+w[x]])                //选两个 dp[x][y]=max(dp[x][y],dp[x+1][y+2*w[x]])+2*c[x]);elsedp[x][y]=max(dp[x][y],dfs(x+1,y+2*w[x])+2*c[x]);return dp[x][y];
}
dfs(1,0); 

部分背包

一个容量为m的背包,有n个物品,第i个物品的体积为wi,价值为ci,有ki个。

选择若干物品,使得体积总和不超过m的情况下价值总和最大。

记忆化搜索

int dfs(int x,int y)
{if (y>m) return -INF;if (x==n+1) return 0;for (int i=0; i<=k[x]; i++){if (dp[x+1][y+i*w[x]])dp[x][y]=max(dp[x][y],dp[x+1][y+i*w[x]]+c[x]);elsedp[x][y]=max(dp[x][y],dfs(x+1,y+i*w[x])+i*c[x]);}return dp[x][y];
}
dfs(1,0);

递推

for (i=n; i>=1; i--)for (j=0; j<=m; j++)for (l=0; l<=k[i]; l++)dp[i][j]=max(dp[i][j],dp[i+1][j+l*w[i]]+l*c[i]);
dp[1][0]

机器分配

有n家店,每家店都有m台机器,第i家店购买j台机器花费a[i][j]元(可能存在a[i][j]>a[i][j+1]),要购买总共m台机器,求最小花费。

搜索

//机器分配 
dfs(int x,int y,int z)
{if(y>m)return;if(x==n+1){if(y==n+1)ans=min(ans,z);return;}for(int i=0;i<=m;i++)dfs(x+1;y+i,z+a[x][i]);
}
dfs(1,0,0);

小小的变形

//机器分配 
int dfs(int x,int y)
{if(y>m)return -INF;if(x==n+1){if(y==m)return 0;//再也不需要买机器 return -INF;}for(int i=0;i<=m;i++)dp[x][y]=min(dp[x][y],dfs(x+1,y+i)+a[x][i]);return dp[x][y];
}
dfs(1,0);

记忆化搜索

//机器分配 
int dfs(int x,int y)
{if(y>m)return -INF;if(x==n+1){if(y==m)return 0;//再也不需要买机器 return -INF;}for(int i=0;i<=m;i++)if(dp[x+1][y+i])dp[x][y]=min(dp[x][y],dp[x+1][y+i]+a[x][i]);elsedp[x][y]=min(dp[x][y],dfs(x+1,y+i)+a[x][i]);return dp[x][y];
}
dfs(1,0);

递推

for(int i=n;i>=1;i--)for(int j=0;j<=m;j++){dp[i][j]=INF;for(k=0;k<=m-j;k++)dp[i][j]=min(dp[i][j],dp[i+1][j+k]+a[i][k]);}
ans=dp[1][0]

烽火传递

给定n个非负整数,选择其中若干数字,使得每连续k个数中至少有一个数被选出。

要求选择的数字之和尽可能小。

搜索

void dfs(int x,int y)
{if(x==n+1){ans=min(ans,y);return;}for(int i=x+1;i<=min(n+1,x+k);i++)dfs(i,y+a[i]);//i是下一个 
}
dfs(0,0);

记忆化

int dfs(int x)
{if(x==n+1)return 0;dp[x]=INF;for(int i=x+1;i<=min(n+1,x+k);i++)if(dp[i])dp[x]=min(dp[x],dp[i]+a[i]);elsedp[x]=min(dp[x],dfs(i)+a[i]);return dp[x];
}
dfs(0);

递推

/*dp[n+1]=0;
dp[1]  dp[2] dp[3] .. dp[1+k]*/for (i=n; i>=0; i--)
{dp[i]=INF;for (int j=i+1; j<=min(n+1,i+k); j++)dp[i]=min(dp[i],dp[j]+a[j]);
}
dp[0]

花店橱窗问题

给定一个n*m的矩阵A(n<=m),求一个序列a1,a2,…,an满足1<=a1<a2<…<an<=m。使得A[1][a1]+A[2][a2]+…+A[n][an]最大。A可能有负数。

搜索

void dfs(int x,int y,int z)
{if(x==n+1){if(y==m+1)ans=max(ans,z);return;}for(int i=y+1;i<=m;i++)dfs(x+1,i,z+a[x+1][i]);
}
dfs(0,0,0);

记忆化搜索

int dfs(int x,int y)
{if(x==n+1){if(y==m+1)return 0;else return -INF;}for(int i=y+1;i<=m;i++){if(dp[x+1][i])dp[x][y]=max(dp[x][y],dp[x+1][i]+a[x+1][i]);elsedp[x][y]=max(dp[x][y],dfs(x+1,i)+a[x+1][i]);return dp[x][y];}
}
dfs(0,0);

递推

/*dp[n+1][m+1]=0; dp[n+1][0~m]=-INF;
dp[1][]  dp[2][] dp[3][]*/
for (i=n; i>=0;i--)for (j=0; j<=m+1; j++)for (k=j+1; k<=m+1; k++)dp[i][j]=max(dp[i][j],dp[i+1][k]+a[i+1][k]);
cout<<dp[0][0];

 

转载于:https://www.cnblogs.com/thmyl/p/7359328.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/269629.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java的小区车辆管理系统_基于Java的小区车辆信息管理系统的设计与实现

软件设计开发 ComputerKnowledgeand Technology 电脑知识 第13卷第2期 (2017年1月) 基于Java的小区车辆信息管理系统的设计与实现 陈小虎&#xff0c;邓惠俊 (万博科技职业学院 计算机科学技术系&#xff0c;安徽 合肥230031) 摘要&#xff1a;世界经济与技术的发展、生活水平的…

Git使用命令行回退版本git reset --hard

git log--oneline --oneline 标记的作用是把每一个提交信息压缩为一行。默认情况下只会展示提交 ID与提交信息的首行。git log --oneline的结果如下 方法一&#xff1a; git reset --hard~回退几个版本 git reset --hard~3 表示回退三个版本&#xff0c;即从8309203回到93b1…

java 测试工具 oracle_几种测试工具的简单介绍

负载测试(LoadTest)&#xff1a;负载测试是一种性能测试&#xff0c;指数据在超负荷环境中运行&#xff0c;程序是否能够承担。 二、WinRunnerWinRunner是一种企业级的功能测试工具&#xff0c;用于检验企业应用程序是否能如期进行&#xff0c;是几款最好的测试工具之一&#x…

【玩转Eclipse】——eclipse实现代码块折叠-类似于VS中的#region……#endregion

【玩转Eclipse】——eclipse实现代码块折叠-类似于VS中的#region……#endregion http://www.cnblogs.com/Micheal-G/articles/5073778.html 转载于:https://www.cnblogs.com/Jeremy2001/p/6708679.html

Git分支命令学习使用

git branch 查看分支&#xff0c;如下图 黄色的有*号的表示当前分支 git branch 分支名 表示创建一个新分支 git checkout 分支名 表示切换到这个分支 git checkout -b 分支名 表示创建这个新分支并且切换到这个分支上

java ioexception异常_12. Java IO: 异常处理

想要查看此教程的目录请点击&#xff1a;Java IO教程目录贴地址Streams或Readers/Writers在使用过程中需要是可关闭的。这需要调用close()方法。这需要一点儿思考&#xff0c;看下面的代码&#xff1a;InputStream input new FileInputStream("c:\\data\\input-text.txt&…

NYOJ--927--dfs--The partial sum problem

/*Name: NYOJ--927--The partial sum problemAuthor: shen_渊 Date: 15/04/17 19:41Description: DFS,和 NYOJ--1058--dfs--部分和问题 基本一致&#xff0c;递归的i1注意了&#xff0c;其他没什么 */#include<cstring> #include<iostream> using namespace std; …

php 中如何重载父类的方法_PHP中子类重载父类的方法【parent::方法名】

在PHP中不能定义重名的函数&#xff0c;也包括不能再同一个类中定义重名的方法&#xff0c;所以也就没有方法重载。单在子类中可以定义和父类重名的方法&#xff0c;因为父类的方法已经在子类中存在&#xff0c;这样在子类中就可以把从父类中继承过来的方法重写。子类中重载父类…

HTML5新特性-自定义属性(data-set)

设么是data-set 在HTML5中我们可以使用data-前缀设置我们需要的自定义属性&#xff0c;来进行一些数据的存放 使用data-set可以获取这些数据 实例 <div id2 data-food皮皮虾></div> <script type"text/javascript">var len document.getElementBy…

php提交表单处理,PHP表单处理

我们可以在PHP中创建和使用表单。要获取表单数据&#xff0c;需要使用PHP超级元组&#xff1a;$_GET和$_POST。表单请求可以是get或post。 要从get请求中检索数据&#xff0c;需要使用$_GET&#xff0c;而$_POST用于检索post请求中的数据。PHP GET表单GET请求是表单的默认请求。…

git中--soft和--mixed和--hard区别

想cvbnm&#xff0c;。、、、、、

Python爬虫1-----------placekitten 入门

常用的urllib库有三个类&#xff1a;request&#xff0c;parse&#xff0c;error&#xff0c;request主要完成对url的请求&#xff0c;如proxy&#xff0c;opener&#xff0c;urlopen&#xff0c;parse主要完成对html的解析&#xff0c;error负责异常处理。 1 import urllib.re…

php标签调用,phpcms栏目标签调用代码大全

phpcms栏目标签调用代码大全$CATEGORY[$catid][catid] 栏目id$CATEGORY[$catid][module] 栏目所在的模块$CATEGORY[$catid][type] 栏目类型$CATEGORY[$catid][modelid] 栏目所属模型id$CATEGORY[$catid][catname] 栏目名称$CATEGORY[$catid][style] 栏目名称样式$CATEGORY[$cat…

怎样在mac系统里将文件拷贝到移动硬盘教程

一&#xff1a;下载这个mounty软件 地址https://mounty.app/ 下载安装 打开后菜单栏显示一座山&#xff0c;如下 接着就可以移动了

前端开发规范文档(html,css,js)

首先吐槽一句,本来想上传word文档的,可是发现博客不能上传word文档,这就很尴尬了。 首先声明该规范不是本人写的,网上搜前端规范发现这个很详细就先复制下来做笔记,当然不可能啥都按规范来,每个公司的规范都不一样..仅供参考 前端开发规范文档 Html规范 1 代码风格 1.1 缩进 **…

Error:java: 无效的目标发行版: 11解决方案

我们在使用Idea开发中如果遇到你的JDK版本有“无效的目标发行版: 11”冲突时&#xff0c;要修改以下JDK版本

php str cmp,php中整数的strcmp equivalent(intcmp)

所以我们在PHP中得到了这个函数strcmp(string $1,string $2) // returns -1,0, or 1;但是,我们没有一个intcmp();所以我创建了一个:function intcmp($a,$b) {if((int)$a (int)$b)return 0;if((int)$a > (int)$b)return 1;if((int)$a < (int)$b)return -1;}这只是感觉脏。…

php现在编辑pdf,用PHP编辑PDF?

用PHP编辑PDF&#xff1f;有谁知道在PHP中编辑PDF的好方法&#xff1f; 优选地是开源/零许可证成本方法。:)我正在考虑打开PDF文件&#xff0c;替换PDF中的文本然后写出PDF的修改版本&#xff1f;我过去使用FPDF以编程方式创建了PDF文件&#xff0c;但有时发现它有点笨拙。kayb…

java证明ArrayList是线程不安全的

证明ArrayList是线程不安全的 我们开启100个线程.每个线程向List加100个数据,那么当所有线程执行完成之后应该是10000条,然后就对比一下结果,看看是否为10000条. thread.join(); 是让主线程等待所有的子线程执行完,才执行接下来的语句 运行结果为9988,而且每次运行结果还不一…