poj 2288 Islands and Bridges (状压dp+Tsp问题)
这道题千辛万苦啊!
这道题要涉及到当前点和前面两个点,那就设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;
}
poj 2288 Islands and Bridges (状压dp+Tsp问题)的更多相关文章
- 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> ...
- [poj2288] Islands and Bridges (状压dp)
Description Given a map of islands and bridges that connect these islands, a Hamilton path, as we al ...
- POJ 1185 炮兵阵地(状压DP)
炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 26426 Accepted: 10185 Descriptio ...
- POJ 2411 Mondriaan's Dream -- 状压DP
题目:Mondriaan's Dream 链接:http://poj.org/problem?id=2411 题意:用 1*2 的瓷砖去填 n*m 的地板,问有多少种填法. 思路: 很久很久以前便做过 ...
- POJ 2411 Mondriaan's Dream ——状压DP 插头DP
[题目分析] 用1*2的牌铺满n*m的格子. 刚开始用到动规想写一个n*m*2^m,写了半天才知道会有重复的情况. So Sad. 然后想到数据范围这么小,爆搜好了.于是把每一种状态对应的转移都搜了出 ...
- 【POJ 2923】Relocation(状压DP+DP)
题意是给你n个物品,每次两辆车运,容量分别是c1,c2,求最少运送次数.好像不是很好想,我看了网上的题解才做出来.先用状压DP计算i状态下,第一辆可以运送的重量,用该状态的重量总和-第一辆可以运送的, ...
- POJ 1185 炮兵阵地 (状压DP)
题目链接 题意 : 中文题不详述. 思路 :状压DP,1表示该位置放炮弹,0表示不放.dp[i][j][k],代表第 i 行的状态为k时第i-1行的状态为 j 时放置的最大炮弹数.只是注意判断的时候不 ...
- 动态规划晋级——POJ 3254 Corn Fields【状压DP】
转载请注明出处:http://blog.csdn.net/a1dark 分析:刚开始学状压DP比较困难.多看看就发现其实也没有想象中那么难.这道题由于列数较小.所以将行压缩成二进制来看.首先处理第一行 ...
- POJ 1185 炮兵阵地 【状压DP】
<题目链接> 题目大意: 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平 ...
随机推荐
- css下背景渐变与底部固定的蓝天白云
<?php defined('_JEXEC') or die; JHtml::_('behavior.framework', true); //if(!$templateparams->g ...
- 【ACM-ICPC 2018 南京赛区网络预赛 L】Magical Girl Haze
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 定义dis[i][j]表示到达i这个点. 用掉了j次去除边的机会的最短路. dis[1][0]= 0; 在写松弛条件的时候. 如果用 ...
- HDU5130 Signal Interference
/* HDU5130 Signal Interference http://acm.hdu.edu.cn/showproblem.php?pid=5130 计算几何 圆与多边形面积交 * */ #in ...
- 计算机网络系统--Microsoft Lync 与 腾讯通RTX 对比(转载)
原文网址: http://it.vsharing.com/226.html ------------------------------- 上海大学统一通信平台现在尚未实施,一直在测试微软的Lync. ...
- python:单引号,双引号和三引号
python中字符串可以用单引号括起来,也可以用双引号,这两种方式是等价的需要表示一个字符串对象的话,单引号和双引号没有区别 为什么需要单引号和双引号同时支持,而一般都是”呢? 比如” 双引号’里面有 ...
- HorizontalDragLayout-模仿QQclient的Item滑动删除
首先感谢http://blog.csdn.net/lmj623565791/article/details/46858663hongyang的文章.之前看过ViewDragHelper类也读过一些de ...
- Mina airQQ聊天 client篇(三)
开发工具 (FlashBuilder4.7) 程序类型(Adobe Air) Flex Air做的桌面程序,效果还挺好看的.最主要是Socket这一块,它也是异步的,而且在Flex中的事件机制比較强大 ...
- JavaScript——BOM(浏览器对象模型),时间间隔和暂停
BOM(浏览器对象模型):能够对浏览器的窗体进行訪问和操作 1.主要的BOM体系: window------------document-------------------------------- ...
- 【为小白菜打call】
作为本校的竞赛生,我必须为我大OJ打call caioj,小白菜oj,顾名思义,就是为刚踏进OI的“小白菜”们准备的网站,里面包含了许多专题内容,各种模版和讲解视频 而且对于刚学习C++的同学,更有帮 ...
- nyoj--95--众数问题(水题)
众数问题 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 所谓众数,就是对于给定的含有N个元素的多重集合,每个元素在S中出现次数最多的成为该元素的重数, 多重集合S重的重 ...