3.4 熟练掌握动态规划——状态压缩DP

从旅行商问题说起——

  给定一个图,n个节点(n<=15),求从a节点出发,经历每个节点仅一次,最后回到a,需要的最短时间。

分析:

  设定状态S代表当前已经走过的城市的集合,显然,S<=(1<<n)-1.

  dp[k][s]——从a走到k,已经经历过的节点集合为s,按照规则走回a所需要的最短时间。

  初始化:dp[k][s]=-1

  

int DP(int K,int S)
{
	if (dp[K][S]!=-1)
	{
		return dp[K][S];
	}
	if (K==a && S==(1<<n)-1)
	{
		//已经走回了A,并且所有点都走过一次
		return dp[K][S]=0;
	}
	dp[K][S]=INF;
	for (int i=0;i<adj[K].size();i++)
	{
		//枚举K的下一个点
		int v=edges[adj[K][i]].to;
		int dist=edges[adj[K][i]].dist;
		if (!(S>>(v-1) & 1))//如果这个点还没有走过
		{
			int val=DP(v,S | (1<<(v-1)));
			if (val!=INF)
			{
				dp[K][S]=min(dp[K][S],val+dist);
			}
		}
	}
	return dp[K][S];
}

  

时间: 2024-10-09 19:12:50

3.4 熟练掌握动态规划——状态压缩DP的相关文章

动态规划之状态压缩dp入门

状态压缩动态规划(简称状压dp)是另一类非常典型的动态规划,通常使用在NP问题的小规模求解中,虽然是指数级别的复杂度,但速度比搜索快,其思想非常值得借鉴. 为了更好的理解状压dp,首先介绍位运算相关的知识. 1.'&'符号,x&y,会将两个十进制数在二进制下进行与运算,然后返回其十进制下的值.例如3(11)&2(10)=2(10). 2.'|'符号,x|y,会将两个十进制数在二进制下进行或运算,然后返回其十进制下的值.例如3(11)|2(10)=3(11). 3.'^'符号,x^y

poj1185炮兵布阵结题报告--初步了解--状态压缩dp

好吧,借助poj1185炮兵布阵这题,仔仔细细的了解了一下状态压缩动态规划 首先,借助题目,我们来看看状态压缩是个虾米东西..Ok follow me 一,所谓状态压缩 根据题意,我们得在长度为M 的地图上放置一些大炮(后面简称"放炮",应该不会被和谐吧),那么,首先不考虑山地,我们得把所有的放置方法都找出来,并且注意,这里只对于一行且长度为M(好吧,你可能要问考虑一行,左右互相隔2,互相不在攻击范围,那么上下呢?这里先不急,一步步来) 1,找出所有放炮的方法 假设长度为7,那么看下图

bzoj1725: [Usaco2006 Nov]Corn Fields牧场的安排(状态压缩DP)

本来就是一个写不大来动态规划的人,结果现在又了解到还有种东西叫状态压缩dp,唉... 找了一道例题来试试看:http://www.lydsy.com/JudgeOnline/problem.php?id=1725 解:我们用f[i][j]来表示当前第i行,状态为j的情况下,(且之前的1~i-1的方案数已经确定了),前i行有多少种方案,那么动态转移方程其实很明显: f[i][j]=sum(f[i-1][k]);(当上一行为第k种状态且与当前枚举的第i种状态不会产生相邻的土地,就加上f[i-1][k

hdu5135 Little Zu Chongzhi&#39;s Triangles(状态压缩dp)

题目链接:点击打开链接 题意描述:给定n(3=<n<=12)节木棍,从中选取一些组成多个三角形,每个三角形由3节木棍组成.问组成的三角形面积之和最大为多少? 解题思路: 刚开始暴力搜索发现当n=12时最多可以组成4个三角形,如果暴力搜索O(4^12==2^24)果断tle 所以考虑动态规划,由于n最大为12所以我们可以用二进制 表示是否要某节木棍.先预处理出每种可能的三角形,然后动态规划即可 代码: #include <cstdio> #include <cmath>

ZJU 1346 Comparing Your Heroes 状态压缩DP 拓扑排序的计数

做多校的时候遇见一个求拓扑排序数量的题,就顺便来写了一下. 题意: 你有个朋友是KOF的狂热粉丝,他有一个对其中英雄的强弱比较,让你根据这些比较关系来给这些英雄排名.问一共有多少种排名方式. 思路: 用dp[S]记录当前状态的数量. S表示拓扑排序中当前阶段已经被排序的点的集合.然后就可以枚举当前排序的点,转移的条件是这个点的所有前驱都被排序,而且这个点没被排序.然后转移就好了,最终状态就是所有点都完成排序. 代码: 1 #include <iostream> 2 #include <c

[知识点]状态压缩DP

// 此博文为迁移而来,写于2015年7月15日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w6jf.html 1.前言 动态规划,永远的痛. 好了不扯远了.状态压缩动态规划,其实看名字还是较好理解的.我们在动态规划的时候,最重要的就在于状态的设计和状态转移方程.那么,如果当我们状态过多导致时间或空间不够的饿时候,就可以用到状态压缩.王队(@wyh2000)说状态压缩DP难起来的话会很难,但是今天我们只讲最最最基础

[转]状态压缩dp(状压dp)

状态压缩动态规划(简称状压dp)是另一类非常典型的动态规划,通常使用在NP问题的小规模求解中,虽然是指数级别的复杂度,但速度比搜索快,其思想非常值得借鉴. 为了更好的理解状压dp,首先介绍位运算相关的知识. 1.'&'符号,x&y,会将两个十进制数在二进制下进行与运算,然后返回其十进制下的值.例如3(11)&2(10)=2(10). 2.'|'符号,x|y,会将两个十进制数在二进制下进行或运算,然后返回其十进制下的值.例如3(11)|2(10)=3(11). 3.'^'符号,x^y

POJ 3254 Corn Fields 状态压缩DP (C++/Java)

http://poj.org/problem?id=3254 题目大意: 一个农民有n行m列的地方,每个格子用1代表可以种草地,而0不可以.放牛只能在有草地的,但是相邻的草地不能同时放牛, 问总共有多少种方法. 思路: 状态压缩的DP. 可以用二进制数字来表示放牧情况并判断该状态是否满足条件. 这题的限制条件有两个: 1.草地限制. 2.相邻限制. 对于草地限制,因为输入的时候1是可以种草地的. 以"11110"草地分析,就只有最后一个是不可以种草的.取反后得00001  .(为啥取反

HDU1565(状态压缩dp)

方格取数(1) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 8170    Accepted Submission(s): 3095 Problem Description 给你一个n*n的格子的棋盘,每个格子里面有一个非负数.从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数