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" 表示),也可能是平 ...
随机推荐
- 【hdu 4135】Co-prime
[题目链接]:http://acm.hdu.edu.cn/showproblem.php?pid=4135 [题意] 让你求出[a..b]这个区间内和N互质的数的个数; [题解] 利用前缀和,求出[1 ...
- 洛谷—— P3353 在你窗外闪耀的星星
https://www.luogu.org/problem/show?pid=3353 题目描述 飞逝的的时光不会模糊我对你的记忆.难以相信从我第一次见到你以来已经过去了3年.我仍然还生动地记得,3年 ...
- PuTTY介绍、安装、使用
简介 PuTTY是一个Telnet.SSH.rlogin.纯TCP以及串行接口连接软件.较早的版本仅支持Windows平台,在最近的版本中开始支持各类Unix平台,并打算移植至Mac OS X上.除了 ...
- NEFU 109
n最大为2000000000(不知为什么OJ上是1000),若为判断2000000000是素数,则必有一个素数在sqrt(n)内,求出这个范围 的所有素数,其比最大数据小的n'的sqrt(n')也在这 ...
- [CortexM0--stm32f0308]Low Power Mode
问题描写叙述 stm32f0308正常是运行在Run mode下.这样的mode是在reset之后的默认模式.Low Power Mode.即低功耗模式.用于在IC空暇时能够考虑选择进入.使系统耗能减 ...
- hdoj 5092 Seam Carving 【树塔DP变形 + 路径输出】 【简单题】
Seam Carving Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Tot ...
- 9patch生成图片
private Bitmap get_ninepatch(int id,int x, int y, Context context){ // id is a resource id for a val ...
- 请用Java设计一个Least Recently Used (LRU) 缓存
LRU介绍:LRU是Least Recently Used的缩写,即最少使用页面置换算法,是为虚拟页式存储管理服务的, 思路介绍: 能够使用两个标准的数据结构来实现.Map和Queue.由于须要支持多 ...
- IOS开发教程--怎样使用点9图片
事先准备一张图片: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA== ...
- MYSQL Training: MySQL I
让以admin身份登录.源代码: 非常easy的注入 在username输入 admin' OR '1'='1 OK.