关于DP和背包
听说过动态规划(DP)的同学应该都知道有背包问题的存在。
首先我们来了解一下动态规划
基本思想:
动态规划算法通常用于求解具有某种最优性质的问题。
在这类问题中, 可能会有很多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。
动规划算法与分治法类似,其基本思想也是将待求解问题分解为若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。
与分治法不同的是,适用于动态规划算法求解的问题,经分解得到的子问题往往不是互相独立的。
若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算很多次。
如果我们能保存已解决子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。
我们可以用一个表来记录所有已解决的子问题的答案。
不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。
这就是动态规划算法的基本思路。具体的动态规划算法多种多样,但它们具有相同的填表格式。
与分治法最大的差别是:适用于动态规划求解的问题,经分解后得到的子问题往往不是互相独立的(即下一个子阶段的求解是建立在上一个子阶段的解的基础上,进行进一步的求解)
应用场景:
适用于动态规划的问题必须满足最优化原理、无后效性和重叠性。
(1) 最优化原理(最优子结构性质):一个最优化策略具有这样的性质,不论过去状态和决策如何,对前面的决策所形成的状态而言,余下的决策必须构成最优策略。简而言之,一个最优化策略的子策略总是最优的。一个问题满足最优化原理又称其具有最优子结构性质。
(2) 无后效性:将各阶段按照一定的次序排列好之后,对于某个给定的阶段状态,它以前各阶段的状态无法直接影响它未来的决策,而只能通过当前的这个状态。换句话说,每个状态都是过去历史的一个完整总结。这就是无后向性,又称无后效性。
(3) 子问题的重叠性:动态规划将原来具有指数级时间复杂度的搜索算法改进成了具有多项式时间复杂度的算法。其中的关键在于解决冗余,这就是动态规划算法的根本目的。动态规划实质上是一种以空间换时间的技术,它在实现的过程中,不得不存储产生过程中的各种状态,所以它的空间复杂度要大于其他算法。
接下来,看背包问题,嗯,听起来就很朴素。
其实背包问题也很简单,无非就是在容器一定的情况下,往里面塞东西,但是容器的容量有限,总不能把它撑爆吧,那不就弄巧成拙了,所以我们要把利益和效率最大化。在容器容量一定的情况下,根据物体的体积(质量)等条件来判断如何装才能使容器内所存物体的价值最大。这就用到了背包问题。
首先我们来看的是01背包问题
01背包指在容器容量一定下,每种物品只有一个,告诉你他们的体积(或者其它条件),以及价值,来使价值最大化。
代码:(优化后为二重循环)
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int total_weight,wp_weight,every_jz;
int main() {
cin>>total_weight;
int dp[total_weight];
memset(dp,,sizeof(dp));
cin>>wp_weight;
int w[wp_weight],v[wp_weight];
for(int i=;i<=wp_weight;i++)
cin>>w[i];
for(int i=;i<=wp_weight;i++)
cin>>v[i];
for (int i = ; i <= wp_weight; i++)
for (int j = total_weight; j >=w[i] ; j--)
dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
cout << "总的价值为: " << dp[total_weight] << endl;
return ;
}
进一步的,我们再来看一下完全背包问题
完全背包指在容器容量一定下,每种物品有无数件,告诉你他们每种分别的体积(或者其它条件),价值,力求价值最大化。
代码:(优化后为二重循环)
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int total_weight,wp_weight,every_jz;
int main() {
cin>>total_weight;
int dp[total_weight];
memset(dp,,sizeof(dp));
cin>>wp_weight;
int w[wp_weight],v[wp_weight];
for(int i=;i<=wp_weight;i++)
cin>>w[i];
for(int i=;i<=wp_weight;i++)
cin>>v[i];
for (int i = ; i <= wp_weight; i++)
for (int j = w[i]; j <=total_weight ; j++)
dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
cout << "总的价值为: " << dp[total_weight] << endl;
return ;
}
最后我们来看一下多重背包问题
即容器容量一定下,每种物品有固定件数,告诉你他们每种分别的体积(或者其它条件),价值,自然还是令价值最大化。
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int total_weight,w_weight;
int main() {
cin>>total_weight>>w_weight;
int w[w_weight],v[w_weight],cot[w_weight],dp[total_weight+];
memset(dp,,sizeof(dp));
for (int i = ; i <= w_weight; i++)
for (int k = ; k <= cot[i]; k++)
for (int j = total_weight; j >= w[i]; j--)
dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
cout << "总的价值为: " << dp[total_weight] << endl;
return ;
}
一世安宁
关于DP和背包的更多相关文章
- USACO Money Systems Dp 01背包
一道经典的Dp..01背包 定义dp[i] 为需要构造的数字为i 的所有方法数 一开始的时候是这么想的 for(i = 1; i <= N; ++i){ for(j = 1; j <= V ...
- 树形DP和状压DP和背包DP
树形DP和状压DP和背包DP 树形\(DP\)和状压\(DP\)虽然在\(NOIp\)中考的不多,但是仍然是一个比较常用的算法,因此学好这两个\(DP\)也是很重要的.而背包\(DP\)虽然以前考的次 ...
- HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化)
HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化) 题意分析 先把每种硬币按照二进制拆分好,然后做01背包即可.需要注意的是本题只需要求解可以凑出几种金钱的价格,而不需要输出种数 ...
- HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化)
HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化) 题意分析 给出一系列的石头的数量,然后问石头能否被平分成为价值相等的2份.首先可以确定的是如果石头的价值总和为奇数的话,那 ...
- HDOJ(HDU).2191. 悼念512汶川大地震遇难同胞――珍惜现在,感恩生活 (DP 多重背包+二进制优化)
HDOJ(HDU).2191. 悼念512汶川大地震遇难同胞――珍惜现在,感恩生活 (DP 多重背包+二进制优化) 题意分析 首先C表示测试数据的组数,然后给出经费的金额和大米的种类.接着是每袋大米的 ...
- HDOJ(HDU).4508 湫湫系列故事――减肥记I (DP 完全背包)
HDOJ(HDU).4508 湫湫系列故事――减肥记I (DP 完全背包) 题意分析 裸完全背包 代码总览 #include <iostream> #include <cstdio& ...
- HDOJ(HDU).1284 钱币兑换问题 (DP 完全背包)
HDOJ(HDU).1284 钱币兑换问题 (DP 完全背包) 题意分析 裸的完全背包问题 代码总览 #include <iostream> #include <cstdio> ...
- HDOJ(HDU).1114 Piggy-Bank (DP 完全背包)
HDOJ(HDU).1114 Piggy-Bank (DP 完全背包) 题意分析 裸的完全背包 代码总览 #include <iostream> #include <cstdio&g ...
- HDOJ(HDU).3466 Dividing coins ( DP 01背包 无后效性的理解)
HDOJ(HDU).3466 Dividing coins ( DP 01背包 无后效性的理解) 题意分析 要先排序,在做01背包,否则不满足无后效性,为什么呢? 等我理解了再补上. 代码总览 #in ...
- POJ.3624 Charm Bracelet(DP 01背包)
POJ.3624 Charm Bracelet(DP 01背包) 题意分析 裸01背包 代码总览 #include <iostream> #include <cstdio> # ...
随机推荐
- .net通用类型转换方法
由于数据类型多,要按照逐个类型写一个类型转换的方法的话一是代码量多,显得累赘. using System; using System.ComponentModel; using System.Glob ...
- MySql EF6 DBFirst 向导无法生成 edmx 解决方法(同:您的项目引用了最新实体框架;但是,找不到数据链接所需的与版本兼容的实体框架数据库提供程序)
使用 MySql EF6 DBfirst 生成模型时经常会遇到EF6模式无法选择的情况究其原因, 还是因为没有正确的使用 Connector/Net. 下面说一下使用方法. 使用 MySql DBFi ...
- sonarQube环境搭建--常见问题及解决
环境配置:MySQL Server 5.7 Jdk1.8 1.安装mysql数据库(默认安装一路默认到底,注意不要先新建用户账号) a) Mysql 环境变量配置: b)新增my.ini文件: ...
- 《CDN 之我见》原理篇——CDN的由来与调度
CDN是将源站内容分发至全国所有的节点,从而缩短用户查看对象的延迟,提高用户访问网站的响应速度与网站的可用性的技术.它能够有效解决网络带宽小.用户访问量大.网点分布不均等问题. 为了让大家更全面的了解 ...
- 铁乐学python_day28_模块学习3
大部份内容摘自授课老师的博客http://www.cnblogs.com/Eva-J/ OS模块复习一二 >>> import os >>> os.getcwd() ...
- centos7.4之zabbix4.0的fping监控
参考博文: https://www.cnblogs.com/lei0213/p/8859326.html 注释:他是额外安装fping的:因为我yum安装的zabbix,fping就已经自带了:安装步 ...
- idea html热部署
IDEA SpringBoot 热部署+html修改无需make自动刷新 收藏 HeyS1 发表于 3个月前 阅读 310 收藏 2 点赞 0 评论 0 特邀IBM大咖的主题沙龙,5月20日·北京·3 ...
- MySQL安装俩个不同版本服务出现的问题(1053)
在使用命令mysqld --install servicename --defaults-file='file_name'创建mysql服务时,系统 已提示创建服务成功,但是net start命令提示 ...
- 【笔记】关于TCP三次握手和四次挥手的理解
1. 三次握手: 服务器一定处于Listen状态,否则客户端发过来的连接会被拒绝.注:服务器和客户端的角色是相对的. 客户端发送第一次握手(客户端发送连接请求(SYNC包)到服务器)之后由Closed ...
- 在远程登陆的主机上通过命令行源码编译安装 GNU M4、autoconf、automake 等程序
由于实验需要,最近获得了一个实验室服务器的账号,平常主要通过 ssh 进行远程登陆进行实验.一方面,远程登录的机器只提供终端界面,一般只通过命令行进行任务操作:另一方面,由于是多人共享服务器,故而个人 ...