CH0103最短Hamilton路径 & poj2288 Islands and Brigdes【状压DP】
虐狗宝典学习笔记:
取出整数\(n\)在二进制表示下的第\(k\)位 \((n >> k) & 1)\)
取出整数\(n\)在二进制表示下的第\(0 ~ k - 1\)位(后\(k\)位) \(n & ((1 << k) - 1)\)
把整数\(n\)在二进制表示下的第\(k\)位取反 \(n xor (1 << k)\)
对整数\(n\)在二进制表示下的第\(k\)为赋值\(1\) \(n | (1 << k)\)
对整数\(n\)在二进制表示下的第\(k\)位赋值\(0\) \(n & (~(1 << k))\)
CH0103---最短Hamilton路径
题意:
hamilton指的是每个节点经过一次且仅经过一次的路径。现在路径上有权值,问最短的路径长度。
思路:
状压dp。\(dp[i][j]\)表示在状态是\(i\)且最后一个经过的点时\(j\)时的最短路径长度。
\(dp[i][j] = min{dp[i xor (i << j)][k] + weight(k, j)}\)
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL; int n;
int g[][];
int dp[ << ][]; int main()
{
scanf("%d", &n);
memset(dp, 0x3f, sizeof(dp));
for(int i = ; i < n; i++){
for(int j = ; j < n; j++){
scanf("%d", &g[i][j]);
}
}
dp[][] = ;
for(int i = ; i < << n; i++){
for(int j = ; j < n; j++){
if(i >> j & ){
for(int k = ; k < n; k++){
if((i ^ << j) >> k & ){
dp[i][j] = min(dp[i][j], dp[i ^ << j][k] + g[k][j]);
}
}
}
}
} printf("%d\n", dp[( << n) - ][n - ]);
return ;
}
poj2288---Islands and Bridges
http://poj.org/problem?id=2288
题意:
有n个岛,m座桥。每座岛有一个val,一条汉密尔顿路径的值是路径中所有点的val之和,加上所有路径上相邻的两个岛的val乘积之和,加上路径上相邻的三个岛的val乘积之和。求最大的值以及方案数。
思路:
和CH0103很相近,不同的是这道题要多存一个岛。\(dp[stat][i][j]\)表示当前状态是\(stat\),最后一个走的岛是\(j\),倒数第二个走的岛是\(i\), \(num\)数组表示对应的方案数。
当\( (stat, i, j) \)可达时,我们检查下一个要走的岛\(k\),如果此时\( (stat >> k) & 1 == 0 \) 且 \( g[j][k] == 1 \)说明\(k\)是满足条件的
设\(tmp\)是下一个走\(k\)时的总价值。那么,\(dp[stat | (1 << k)][j][k] = max(dp[stat | (1 << k)][j][k], tmp)\)
如果\(tmp == dp[stat | (1 << k)][j][k]\),那么,\(num[stat | (1 << k)][j][k] += num[stat][i][j]\)。否则\(num[stat | (1 << k)][j][k] = num[stat][i][j] \)
那么要如何求\(tmp\) 呢。
首先当\(j\)可以走到\(k\)时,肯定有 \(tmp = dp[stat][i][j] + val[k] + val[j] * val[k] \)
如果此时还有\(g[i][k] == 1\) 那么\(tmp += val[i] * val[j] * val[k]\)
最后我们对于\(stat = (1 << n) - 1\)枚举\(i\)和\(j\),找到最大的结果。
注意方案数会超出int。还需要注意\(n = 1\)时的特殊情况。
注意内存省着点,会MLE
//#include <bits/stdc++.h>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <stdio.h>
#include <vector>
#include <map>
#include <set>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL; int n, m, q;
bool g[][];
int dp[ << ][][];
LL num[ << ][][];
int val[];
int cnt; void hamilton()
{
memset(dp, -, sizeof(dp));
memset(num, , sizeof(num));
for(int i = ; i < n; i++){
for(int j = ; j < n; j++){
if(g[i][j]){
dp[ << i | << j][i][j] = val[i] + val[j] + val[i] * val[j];
num[ << i | << j][i][j] = ;
}
}
} for(int stat = ; stat < << n; stat++){
for(int i = ; i < n; i++){
if((stat >> i) & ){
for(int j = ; j < n; j++){
if((stat >> j) & ){
if(g[i][j] && dp[stat][i][j] != -){
for(int k = ; k < n; k++){
if(g[j][k] && k != i && ((stat >> k) & ) == ){
int tmp = dp[stat][i][j] + val[k] + val[k] * val[j];
if(g[i][k]){
tmp += val[i] * val[j] * val[k];
}
if(tmp > dp[stat | ( << k)][j][k]){
dp[stat | ( << k)][j][k] = tmp;
num[stat | ( << k)][j][k] = num[stat][i][j];
}
else if(tmp == dp[stat | ( << k)][j][k]){
num[stat | ( << k)][j][k] += num[stat][i][j];
}
}
}
}
}
}
}
}
}
//return dp[(1 << n) - 1][n - 1];
} int main()
{
scanf("%d", &q);
while(q--){
memset(g, , sizeof(g));
scanf("%d%d", &n, &m);
for(int i = ; i < n; i++){
scanf("%d", &val[i]);
}
for(int i = ; i < m; i++){
int u, v;
scanf("%d%d", &u, &v);
g[u - ][v - ] = ;
g[v - ][u - ] = ;
}
if(n == ){
printf("%d 1\n", val[]);
continue;
} hamilton();
int maxi = ;
LL ans = ;
for(int i = ; i < n; i++){
for(int j = ; j < n; j++){
if(g[i][j]){
if(maxi < dp[( << n) - ][i][j]){
maxi = dp[( << n) - ][i][j];
ans = num[( << n) - ][i][j];
}
else if(maxi == dp[( << n) - ][i][j]){
ans += num[( << n) - ][i][j];
}
}
}
} printf("%d %lld\n", maxi, ans / );
}
return ;
}
CH0103最短Hamilton路径 & poj2288 Islands and Brigdes【状压DP】的更多相关文章
- [poj2288] Islands and Bridges (状压dp)
Description Given a map of islands and bridges that connect these islands, a Hamilton path, as we al ...
- CH0103 最短Hamilton路径 dp
正解:状压dp 解题报告: 完了吃枣退役:D 我是真的没想到这是个dp...脑子越来越不好了,大概是太久没碰OI了都要生疏了...哭了,感觉自己太傻逼了可能不适合学信息... 知道是个状压dp就eas ...
- poj 2288 Islands and Bridges ——状压DP
题目:http://poj.org/problem?id=2288 状压挺明显的: 一开始写了(记忆化)搜索,但一直T: #include<iostream> #include<cs ...
- poj 2288 Islands and Bridges——状压dp(哈密尔顿回路)
题目:http://poj.org/problem?id=2288 不知为什么记忆化搜索就是WA得不得了! #include<iostream> #include<cstdio> ...
- 『最短Hamilton路径 状态压缩DP』
状压DP入门 最短Hamilton路径 Description 给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Hamil ...
- 最短Hamilton路径【状压DP】
给定一张 nn 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每个点恰好一次. 输入 ...
- 位运算 - 最短Hamilton路径
给定一张 n 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每个点恰好一次. 输入格 ...
- 0103 最短Hamilton路径【状压DP】
0103 最短Hamilton路径 0x00「基本算法」例题 描述 给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Ham ...
- 最短Hamilton路径
题目描述 给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每 ...
随机推荐
- HTML5标签canvas图像处理
摘要: canvas可以读取图片后,使用drawImage方法在画布内进行重绘.本文介绍canvas的图像处理 drawImage drawImage() 方法在画布上绘制图像.画布或视频.drawI ...
- 修改Tomcat的默认访问目录
放在外网的应用,用户多是直接输入域名访问,而Tomcat的默认目录是ROOT,所以我们需要更改其默认目录. 更改Tomcat的默认目录很简单,只需要修改server.xml就可以了. 具体是是在< ...
- ios开发之--UITextField光标右移
有时候,我们直接使用TF进行操作,有时候需要裁剪,但是裁剪后,光标还是置顶的,很不美观,解决办法: // 设置一个空白View,15.0就是这块View的宽度width,也是光标的位置,根据需要设定大 ...
- iOS开发之-- 字符串的操作,去掉某一个字符或者替换成其他字符
一个简单的操作,记录下: NSString *strUrl = [urlString stringByReplacingOccurrencesOfString:@" " withS ...
- windows C 設置控制臺文本輸出的顏色(可用作調試使用)
#include <windows.h> #define RED 0x0004 #define GREEN 0x0002 #define BLUE 0x0001 #define WHITE ...
- 彻底关闭Google的安全搜索
在使用简体中文的情况下,访问Google总是会跳转到香港,这个时候的安全搜索是无法关闭的. 下面介绍一个最简单的方法,直接使用Google的中文界面:https://www.google.com/we ...
- 【代码审计】ThinkSNS_V4 任意文件下载漏洞分析
0x00 环境准备 ThinkSNS官网:http://www.thinksns.com 网站源码版本:ThinkSNS V4 更新时间:2017-09-13 程序源码下载:http://www ...
- 基于Cocos2d-x学习OpenGL ES 2.0系列——编写自己的shader(2)
在上篇文章中,我给大家介绍了如何在Cocos2d-x里面绘制一个三角形,当时我们使用的是Cocos2d-x引擎自带的shader和一些辅助函数.在本文中,我将演示一下如何编写自己的shader,同时, ...
- pom.xml文件错误
刚创建的maven项目,马上pom.xml的第一行就报错这是第一行:<project xmlns="http://maven.apache.org/POM/4.0.0" xm ...
- python下安装Scikit-learn
安装SK-Learn需要依赖的Python安装包有: Python (>= 2.6), NumPy (>= 1.3), SciPy (>= 0.7), 下载python的各种包的地址 ...