这道题千辛万苦啊!

这道题要涉及到当前点和前面两个点,那就设dp[state][i][j]为当前状态为state,当前点为i,前一个点为j

这个状态表示和之前做炮兵那题很像,就是涉及到三个点时,就多设一维表示前一个点(炮兵那题把点换成行)

这道题有很多细节需要注意

(1)计算路径长度。这道题一开始怎么不重复又方便的计算长度难住了我。

后来看到题解直接在初始化的时候算上路径,非常牛逼

然后前两个点的路径就包含进去了。

首先加上前一个点和当前点的价值

然后看有没有构成三角形,有就再加上

(2)更新答案。这里更新答案要dp完了之后再弄,在dp时更新会出错

多打几行代码不会死的,重要是要ac,麻烦一点就麻烦一点

(3)初始化问题。这里谈谈填表法和刷表法初始化的不同

如果是刷表法,那么就不知道当前状态合不合理,那就每次都需要判断一下

一般来说一开始全部初始化为-1表示全部不合理,然后就把一开始合理的部分(比如起点)赋初值(一般为0)。

如果是填表法的话,一般来说不需要判断合不合理

但是这道题不一样,并不知道前两个点的状态是否合法,所以需要判断。

(4)这道题有个比较坑的地方,就是n=1时要特判

(5)然后自己头脑一定要清楚哪一个变量是第几个点!!

我一般是写i是当前点,j是前一个点,k是前前个点

(6)下标范围是0到n-1,那么就写1 << n

(7)方案数。这道题方案数最后要除以2,因为可以反着走,但题目里算同一种

然后dp弄方案一般可以开一个数组,意义是和dp数组一模一样的,只不过存的是方案数

然后符合就加上

#include<cstdio>
#include<cstring>
#include<algorithm>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
#define _for(i, a, b) for(int i = (a); i <= (b); i++)
using namespace std;typedef long long ll;
const int MAXN = 15;
int dp[(1 << 13) + 10][MAXN][MAXN], w[MAXN];
int g[MAXN][MAXN], n, m;
ll ways[(1 << 13) + 10][MAXN][MAXN];int main()
{int T;scanf("%d", &T);while(T--){memset(g, 0, sizeof(g));memset(dp, -1, sizeof(dp)); //初始化要注意 memset(ways, 0, sizeof(ways));scanf("%d%d", &n, &m);REP(i, 0, n) scanf("%d", &w[i]);while(m--){int u, v;scanf("%d%d", &u, &v); u--; v--;g[u][v] = g[v][u] = 1;}if(n == 1) { printf("%d 1\n", w[0]); continue; } //特判 REP(i, 0, n) //初始化 REP(j, 0, n)if(g[i][j]){dp[(1<<i)|(1<<j)][i][j] = w[i] + w[j] + w[i] * w[j];ways[(1<<i)|(1<<j)][i][j] = 1;}REP(S, 0, 1 << n)REP(i, 0, n) if(S & (1 << i))REP(j, 0, n) if((S & (1 << j)) && g[i][j])REP(k, 0, n) if((S & (1 << k)) && g[j][k]){if(i == j || j == k || i == k || dp[S^(1<<i)][j][k] == -1) continue; ll t = dp[S^(1<<i)][j][k] + w[i] + w[j] * w[i]; // 注意这里哪一个是最后一点 if(g[i][k]) t += w[i] * w[j] * w[k];if(dp[S][i][j] < t){dp[S][i][j] = t;ways[S][i][j] = ways[S^(1<<i)][j][k];}else if(dp[S][i][j] == t) ways[S][i][j] += ways[S^(1<<i)][j][k]; //这里是else if 写if会错 }ll ans = 0, num = 0; //分开来做 int S = (1 << n) - 1;REP(i, 0, n)REP(j, 0, n)if(g[i][j]){if(ans < dp[S][i][j]){ans = dp[S][i][j];num = ways[S][i][j];}else if(ans == dp[S][i][j])num += ways[S][i][j];}printf("%lld %lld\n", ans, num / 2);}return 0;
}

转载于:https://www.cnblogs.com/sugewud/p/9819326.html

poj 2288 Islands and Bridges (状压dp+Tsp问题)相关推荐

  1. POJ 1185 炮兵阵地 【状压DP】

    <题目链接> 题目大意: 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平 ...

  2. POJ 2288 Islands and Bridges(状压dp)

    http://poj.org/problem?id=2288 题意: 有n个岛屿,每个岛屿有一个权值V,一条哈密顿路径C1,C2,...Cn的值为3部分之和: 第1部分,将路径中每个岛屿的权值累加起来 ...

  3. poj -- 2288 Islands and Bridges

    题意:给你n个岛屿,m条路,每个岛屿都有一个值vi,经过这个岛屿会得到这个值,规则: 1.经过所有的岛屿 sum += vi: 2.连续两个岛屿(即连通) sum += vi * vj: 3.连续三个 ...

  4. POJ - 2411 Mondriaan's Dream(状压dp)

    题目链接:点击查看 题目大意:铺瓷砖 题目分析:经典之经典的状态压缩动态规划,具体的懒得说了,怠惰ing..一个月之前写的代码,还好当时注释做的好,现在稍微一看就能立马理解,码到博客上存着吧,三种方法 ...

  5. POJ 1185 炮兵阵地(状压DP)题解

    思路:和上一篇思路一样,但是这里要求最大能排几个,这里要开三维,记录上次和上上次的状态,再一一判定,状态转移方程为 dp[i][j][k] = max(dp[i][j][k],dp[i - 1][k] ...

  6. POJ 1185 炮兵阵地(状压dp)

    http://poj.org/problem?id=1185 题意: 思路: 每一行最多只有10列,所以可以用二进制来表示每一行的状态. d[i][j][k]表示第i行状态为k时,并且上一行状态为j时 ...

  7. 状压DP TSP不回到原点

    题目大意: 有N个点,你开始在第一个点,现在要求你不重复的遍历所有点(点经过后不能再次经过),问最短距离是多少.2<=N<=16. 有N个点,你开始在第一个点,现在要求你不重复的遍历所有点 ...

  8. CH0103最短Hamilton路径 poj2288 Islands and Brigdes【状压DP】

    虐狗宝典学习笔记: 取出整数\(n\)在二进制表示下的第\(k\)位                                                    \((n >> ...

  9. POJ 1038 Bugs Integrated Inc (复杂的状压DP)

    \(POJ~1038~~*Bugs~Integrated~Inc:\) (复杂的状压DP) \(solution:\) 很纠结的一道题目,写了大半天,就想练练手,结果这手生的.其实根据之前那道炮兵阵地 ...

最新文章

  1. 数据结构 第三周第四周学习小结
  2. mac php 连接mysql数据库_Mac环境下php操作mysql数据库的方法分享_PHP教程
  3. session 存放对象变量,及遇到的奇怪现象
  4. autojsui界面关闭_autojs 第九次 ui界面交互获取
  5. sql2005数据导入出错问题
  6. pytorch中的nan
  7. 02_反汇编_反编译
  8. 统一的Ajax提交封装,一劳永逸好工具(带跨域处理)
  9. 【干货】华为组织成长的动力机制.pdf(附下载链接)
  10. Matlab箱线图Boxplot横坐标x轴设置
  11. [C++/CLI编程宝典][3]C++/CLI能做什么
  12. (转)C++的tie()函数
  13. 事件管理和问题管理,配置管理和变更管理的区别
  14. java程序员面试自我介绍范文
  15. 移动硬盘与电脑连接后 计算机中找不到,移动硬盘连接电脑后不显示盘符怎么办...
  16. 《数值分析》-- 高斯消去法与矩阵三角分解法(LU分解)
  17. 《英国金融科技国家报告》翻译与摘录
  18. 【Java启程】语句结构
  19. c语言 验证用户名密码
  20. 蓝牙a2dp协议源码分析

热门文章

  1. python爬取餐饮数据_Python爬取附近餐馆信息代码示例
  2. mybatis 在语句中使用to_char时报错
  3. 这篇文章告诉你几款必备软件
  4. 【周星驰电影全集下载】年表
  5. 助力企业降本增效的利刃--固定资产盘点系统
  6. 2013:爱你不容易
  7. IP协议的服务类型(翻译RFC 1349)
  8. NetSuite Saved Search 已保存搜索 入门四部曲
  9. PHP学习之旅(Xnova研究)(三)
  10. 欧姆龙转MQTT边缘计算网关(产品)