虐狗宝典学习笔记:

取出整数\(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路径

http://contest-hunter.org:83/contest/0x00%E3%80%8C%E5%9F%BA%E6%9C%AC%E7%AE%97%E6%B3%95%E3%80%8D%E4%BE%8B%E9%A2%98/0103%20%E6%9C%80%E7%9F%ADHamilton%E8%B7%AF%E5%BE%84

题意:

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】的更多相关文章

  1. [poj2288] Islands and Bridges (状压dp)

    Description Given a map of islands and bridges that connect these islands, a Hamilton path, as we al ...

  2. CH0103 最短Hamilton路径 dp

    正解:状压dp 解题报告: 完了吃枣退役:D 我是真的没想到这是个dp...脑子越来越不好了,大概是太久没碰OI了都要生疏了...哭了,感觉自己太傻逼了可能不适合学信息... 知道是个状压dp就eas ...

  3. poj 2288 Islands and Bridges ——状压DP

    题目:http://poj.org/problem?id=2288 状压挺明显的: 一开始写了(记忆化)搜索,但一直T: #include<iostream> #include<cs ...

  4. poj 2288 Islands and Bridges——状压dp(哈密尔顿回路)

    题目:http://poj.org/problem?id=2288 不知为什么记忆化搜索就是WA得不得了! #include<iostream> #include<cstdio> ...

  5. 『最短Hamilton路径 状态压缩DP』

    状压DP入门 最短Hamilton路径 Description 给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Hamil ...

  6. 最短Hamilton路径【状压DP】

    给定一张 nn 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每个点恰好一次. 输入 ...

  7. 位运算 - 最短Hamilton路径

    给定一张 n 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每个点恰好一次. 输入格 ...

  8. 0103 最短Hamilton路径【状压DP】

    0103 最短Hamilton路径 0x00「基本算法」例题 描述 给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Ham ...

  9. 最短Hamilton路径

    题目描述 给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每 ...

随机推荐

  1. 微信企业号OAuth2验证接口实例(使用SpringMVC)

    微信企业号OAuth2验证接口(使用SpringMVC) 企业应用中的URL链接(包含自己定义菜单或者消息中的链接).能够通过OAuth2.0来获取员工的身份信息. 注意.此URL的域名,必须全然匹配 ...

  2. flexbox子盒子order属性

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. js防止表单重复提交

    1.表单 <form id="addForm" onsubmit="getElementById('submitInput').disabled=true;retu ...

  4. Kubernetes kubectl 命令

    kubectl 命令用来操作 Kubernetes 集群中的资源对象,包括对资源的创建.删除.查看.修改.配置.运行等 命令语法:kubectl [command] [TYPE] [NAME] [fl ...

  5. 安装ahci驱动后出现A disk read error occurred如何解决

    注意:因为一般的ghost系统盘都没有ahci驱动,所以,如果用到固态硬盘且想更好的发挥固态硬盘的性能,需要安装ahci驱动,且在bios 中把硬盘模式设置成ahci(否则电脑会蓝屏或进不去系统) 步 ...

  6. Jquery-无法有效获取当前窗口高度

    今天碰到个很奇怪的事情,那就是滚动条往下滚动时候没有触发提示,反而是往上滚动的时候,触发了提示.百思不得其解,尤其是拿了美工大大的切图过来,一点问题都没有. 那么就进行console.log输出查看了 ...

  7. 数据流-------C#文件和byte[]互换问题

    今天使用FileInfo.CopyTo的时候出现问题,当然并不是使用的问题,而是一些细节. 不过报错的时候,一度让我认为,copyto这个方法,给的参数必须是文件夹,而不是文件.所以就有了下面的查找 ...

  8. shell编程(一)

    迷迷糊糊中发现了一个学习shell的非常好的教程,从头到尾看了一下,等看完全忘记了,没办法只能记录下来,教程网址http://c.biancheng.net/cpp/view/6994.html 以前 ...

  9. 【Phalapi2.0】 如何使用 source 通过 header 传参数

    做接口服务时候.有些场景会使用header 来传递参数. 查看官网文档说明 数据来源 source指定当前单个参数的数据来源,可以是post.get.cookie.server.request.hea ...

  10. 【linux系列】Centos下安装mysql数据库

    前言 为了测试方便,通常我们会自己安装数据库,以下是在Centos上安装Mysql的操作. 一.检查自己是否安装了MySQL数据库 [root@s201 /home/mysql]#rpm -qa |g ...