当前位置: 首页 > wzjs >正文

郑州网站建设 郑州网站制作学电脑在哪里报名

郑州网站建设 郑州网站制作,学电脑在哪里报名,hbuilder做php网站,域名不转出可以做网站吗状态压缩动态规划算法 状态压缩动态规划是动态规划的一种,它通过使用位运算的方式压缩程序占用的空间,对于可以用来解决一些只有两个状态(是与否)的问题。 多少无益,我们通过下面的一道编程题目来学习这种算法。 题目…

状态压缩动态规划算法

状态压缩动态规划是动态规划的一种,它通过使用位运算的方式压缩程序占用的空间,对于可以用来解决一些只有两个状态(是与否)的问题。
多少无益,我们通过下面的一道编程题目来学习这种算法。

题目描述:
小明使用霰弹枪打固定靶,假设有M个目标,小明开了N枪。每一枪都有若干目标被命中。现在小明想知道,自己刚刚理论上最少只需要几枪就能打中全部的目标。

假设有3个目标:[0, 0, 0]
小明开了3枪:[1, 0, 0],[0, 1, 0],[0, 1, 1],其中为1表示命中了对应的目标。
结果输出:小明第一枪加第三枪命中了所有的目标,理论上只要两枪就可以全部命中。

假设有3个目标:[0, 0, 0]
小明开了3枪:[1, 0, 0],[0, 1, 0],[1, 1, 0],其中为1表示命中了对应的目标。
结果输出:小明无法全部命中目标。

分析:
这道题有很多不同解法,可以使用贪心算法,但是为了讲解状压动规,这里不使用贪心算法。
使用动态规划解决问题的第一步就是要确定使用动态规划能否解决问题。题干中有一个关键词,最少几枪。更关键的一点是它没有要求我输出到底是哪几枪(如果要求输出哪几枪可能就要用回溯子集了)。因此大家应该条件反射的尝试使用动态规划。
动态规划最重要的一个步骤就是确定动态数组dp与状态转移矩阵。

确定dp数组的含义
首先确认dp的大小,有的同学可能条件反射的认为dp的大小应该是M,对应M个目标。dp[i]表示命中i个目标需要的最小枪数。但是接下来会发现举步维艰,因为都是命中i个目标,如果打中不一样的靶子,反应的是不同的状态。实际上这道题的dp矩阵的索引的含义并不是直接了当的呈现在我们的面前。
提问:当我有M个目标时,我有多少种命中状态?
答:每个目标都有命中与未命中两种状态,M个目标组合起来应该是2的M次方。
在这里插入图片描述
聪明的读者到这里应该恍然大悟一下:原来dp要有2^M个元素,索引反应了目标的命中情况。假设dp[3] = 2,indx = 3的二进制是011b,这里表示命中前两个目标最少需要2枪。

dp数组初始化
明确了dp数组的含义,就需要对dp数组进行初始化了,结合dp数组的含义,我们应该首先明确:
dp[0] = 0:命中0个目标需要开0枪。
假设小明第2枪命中情况为:[1, 0, 1],那么:
dp[101b] = dp[5] = 1:命中第一个与第三个目标只需要一枪。
我们将命中目标用二进制掩码表示,将所有子弹命中的情况对应的dp[indx]置为1即可完成初始化。
这就是这个问题的解决思路,现在我们直接上代码,一些细节用代码来讲述。

完整代码

#include <iostream>
#include <vector>
#include <string>
#include <climits>
using namespace std;int main() {int M, N;		// M个目标 开N枪cin >> M >> N;	// 输入 M 与 Nvector<int> state;	// 装填掩码for (int i = 0; i < N; i++) {int s = 0;for (int j = 0; j < M; j++) {int tmp = 0;cin >> tmp;		//  输入第i枪命中情况,1:命中,0:未命中s = (s << 1) + tmp;}state.push_back(s);}// 对state内的所有数据按位取与,如果tmp = 2^M -1,证明N枪后所有目标都命中int tmp = 0;for (int i : state) {tmp |= i;}if (tmp != (1 << M) - 1) {	cout << "未命中所有目标" << endl;return 0;}// 初始化dp数组int num = (1 << M) - 1;vector<int> dp(num + 1, INT_MAX);dp[0] = 0;for (int i : state) {dp[i] = 1;}// 状态转移,讲解见后文for (int mask : state) {for (int indx = num; indx >= 0; indx--) {if (dp[indx] != INT_MAX) {int new_indx = indx | mask;if (dp[indx] + 1 < dp[new_indx]) {dp[new_indx] = dp[indx] + 1;}}}}cout << "最少需要" << dp[num] << "枪" << endl;return 0;
}

状态转移分析

假设当前命中状态为x0,在第k发子弹的射击下,命中状态x1变为x1 = x0 | state[k];
从状态x0到状态x1,射击次数变为:tmp_num = dp[x0] + 1
结合dp[x1]的定义:命中状态为x1时,需要最少的的射击次数。因此我们需要比较通过x0转移到x1的射击次数tmp_numdp[x1]目前的值:
伪代码:

int x1 = x0 | state[k];	// 这里表示一次射击动作
int tmp_num = dp[x0] + 1;
if(tmp_num < dp[x1]) { dp[x1] = tmp_num;	// 证明由x0到达x1比原本的方案更快 }
else { ;	// 空操作,证明当前到达x1有更快的射击方案 }

小结

上面的讲解就是状态压缩动态规划的一个使用案例与核心逻辑。
之所以选择这种方法有三个关键要素:
1、求最优方案。
2、不要求输出最优方案的具体路径信息。
3、对于最小元素(一个目标),只有是和否(命中/未命中)两种区别。

http://www.dtcms.com/wzjs/243595.html

相关文章:

  • 网站开发合同范本下载提高工作效率的措施
  • 广州景点搜索引擎营销优化的方法
  • 无锡企业网站设计公司成品网站源码的优化技巧
  • 单页网站建设教程域名注册需要哪些条件
  • wordpress插件要求seo是广告投放吗
  • 黄岩做网站seo搜狗
  • wordpress 页面新建如何做好seo优化
  • 网站建设意味着什么网站日常维护有哪些
  • 产品展示的手机网站优化电脑的软件有哪些
  • 有什么网站可以做设计兼职学电子商务出来能干嘛
  • 甘肃做网站公司网站建设需要注意什么
  • 做推广哪些网站好品牌建设
  • 上海大型网站建设公司枣庄网络推广seo
  • 公司做网站是管理费用广告代理
  • 做的网站每年都要交费吗宁德seo优化
  • 如何做美女图片网站网站如何发布
  • 百度网盟推广 网站互联网产品营销策划方案
  • c2c网站建设价格他达拉非片
  • 西安大网站建设公司推广策划方案怎么做
  • 海东市网站建设google推广公司哪家好
  • 网站编辑没有经验可以做吗抖音的商业营销手段
  • 单页网站推广南京百度网站快速优化
  • 无锡华士镇网站建设中国今天刚刚发生的新闻
  • 做运营那些无版权图片网站免费正规大数据查询平台
  • 本地计算机做网站服务器合肥网络关键词排名
  • 专业网站的定义百度推广找谁做
  • 江苏宜安建设有限公司网站友情链接平台站长资源
  • 深圳装饰公司100排名优化设计电子课本下载
  • 网站开发与设计 课程简介平台交易网
  • 河南省网架公司成都网站优化排名推广