POJ 2288 汉密尔顿回路 DP解决
题目大意:
有n个岛屿,令Vi为岛屿Ci的权值。一条汉密尔顿路径C1,C2,C3...Cn的值为3部分
第一部分,将路径中的岛的权值相加,第二部分将每条边上的(Ci,Cj),加上所有的Vi*Vj
第三部分,如果连续经过的3个城市可以形成3角联通,那么加上Vi*Vj*Vk
求出一条路径使其权值最大,并记录有多少可以达到最大权值的路径
1->2->3 , 3->2->1 视为相同路径
这里最多13个城市,所以用2进制表示是否到达当前位置的城市
这里用dp[i][k][j] 表示到达i状态时,最后到达的两个城市为j,k,这样可以达到的最大权值
dp[i|(1<<(t-1)][j][t] = max{dp[i|(1<<(t-1)][j][t] , dp[i][k][j]+val[t]+val[j]*val[t]+ edge[k][t]?val[j]*val[k]*val[t]:0}
注意每次更新dp值同时记录一个到达当前状态的路径数量cnt[i][k][j]
这里要注意只有一个城市的时候要特判
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
using namespace std;
#define N 14
#define ll long long
int n,m;
ll dp[<<N][N][N] , val[N] , cnt[<<N][N][N];//cnt记录当前状态下可行的方法总数
bool edge[N][N]; void getDp()
{
memset(cnt , ,sizeof(cnt));
memset(dp , - , sizeof(dp));
int all = (<<n);
dp[][][]= , cnt[][][]=;
for(int i= ; i<=n ; i++) dp[<<(i-)][][i]=val[i],cnt[<<(i-)][][i]=;
for(int i= ; i<all ; i++){
for(int j= ; j<=n ; j++){
if(!(i&(<<(j-)))) continue;
for(int k= ; k<=n ; k++){
if(k == && (i!=(<<(j-)))) continue;
if(k==j || (!(i&(<<(k-))) && k!=)) continue;
if(dp[i][k][j]<) continue; for(int t= ; t<=n ; t++){
if(!edge[j][t] || i&(<<(t-))) continue;
ll v = dp[i][k][j]+val[t]+val[t]*val[j];
if(edge[t][k]) v = v+val[j]*val[k]*val[t];
int status = i|(<<(t-));
if(dp[status][j][t]< || dp[status][j][t]<v){
dp[status][j][t]=v;
cnt[status][j][t]=cnt[i][k][j];
}
else if(dp[status][j][t] == v){
cnt[status][j][t]+=cnt[i][k][j];
}
//debug
// print(status);cout<<endl;
// cout<<i<<" "<<j<<" "<<k<<" "<<dp[status][k][t]<<endl;
}
}
}
}
} int main()
{
// freopen("a.in" , "r" , stdin);
int T;
scanf("%d" , &T);
while(T--)
{
scanf("%d%d" , &n , &m);
for(int i= ; i<=n ; i++) scanf("%I64d" , val+i);
memset(edge , , sizeof(edge));
int a,b;
for(int i= ; i<m ; i++){
scanf("%d%d" , &a , &b);
edge[a][b]=true;
edge[b][a]=true;
}
getDp();
int all=(<<n);
ll maxn = - , ans=;
for(int i= ; i<=n ; i++)
for(int j= ; j<=n ; j++)
{
maxn=max(maxn,dp[all-][i][j]);
}
if(maxn == -){
puts("0 0");
continue;
}
for(int i= ; i<=n ; i++)
for(int j= ; j<=n ; j++)
if(maxn == dp[all-][i][j]) ans+=cnt[all-][i][j];
/***要注意只有一个城市的情况下要特判***/
printf("%I64d %I64d\n" , maxn , ans/?ans/:);
}
return ;
}
POJ 2288 汉密尔顿回路 DP解决的更多相关文章
- Islands and Bridges(POJ 2288状压dp)
题意:给你一个图和每个点的价值,边权值为连接两点权值的积,走哈密顿通路,若到达的点和上上个点相连则价值加三点乘积,求哈密顿通路的最大价值,和最大价值哈密顿通路的条数. 分析:开始看这个题很吓人,但想想 ...
- UVA1292-----Strategic game-----树形DP解决树上的最小点覆盖问题
本文出自:http://blog.csdn.net/dr5459 题目地址: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&a ...
- POJ.3624 Charm Bracelet(DP 01背包)
POJ.3624 Charm Bracelet(DP 01背包) 题意分析 裸01背包 代码总览 #include <iostream> #include <cstdio> # ...
- 7-4 汉密尔顿回路(25 分) 【STL】
7-4 汉密尔顿回路(25 分) 著名的"汉密尔顿(Hamilton)回路问题"是要找一个能遍历图中所有顶点的简单回路(即每个顶点只访问 1 次).本题就要求你判断任一给定的回路是 ...
- POJ 1390 Blocks (区间DP) 题解
题意 t组数据,每组数据有n个方块,给出它们的颜色,每次消去的得分为相同颜色块个数的平方(要求连续),求最大得分. 首先看到这题我们发现我们要把大块尽可能放在一起才会有最大收益,我们要将相同颜色块合在 ...
- POJ 2995 Brackets 区间DP
POJ 2995 Brackets 区间DP 题意 大意:给你一个字符串,询问这个字符串满足要求的有多少,()和[]都是一个匹配.需要注意的是这里的匹配规则. 解题思路 区间DP,开始自己没想到是区间 ...
- 蓝桥杯 试题 算法提高 宰羊 DP解决
问题描述 炫炫回了内蒙,肯定要吃羊肉啦,所有他家要宰羊吃. 炫炫家有N只羊,羊圈排成一排,标号1~N.炫炫每天吃掉一只羊(这食量!其实是放生啦),吃掉的羊的邻居会以为它被放生了,然后又会告诉他们的邻居 ...
- 蓝桥杯 试题 历届试题 对局匹配 DP解决
问题描述 小明喜欢在一个围棋网站上找别人在线对弈.这个网站上所有注册用户都有一个积分,代表他的围棋水平. 小明发现网站的自动对局系统在匹配对手时,只会将积分差恰好是K的两名用户匹配在一起.如果两人分差 ...
- poj 2288 Islands and Bridges——状压dp(哈密尔顿回路)
题目:http://poj.org/problem?id=2288 不知为什么记忆化搜索就是WA得不得了! #include<iostream> #include<cstdio> ...
随机推荐
- PoolManager插件(转载)
http://www.xuanyusong.com/archives/2974 前几天我在博客里面分享了为什么Unity实例化很慢的原因,并且也分享了一个缓存池的工具.有朋友给我留言说PoolMana ...
- JS内置对象练习(慕课网题目)
效果图: XXXX年XX月X日 星期X--班级总分为:81 格式要求: 1.显示打印的日期. 格式为类似“XXXX年XX月XX日 星期X” 的当前的时间. 2.计算出该班级的平均分(保留整数). 同学 ...
- flex和box兼容性写法
display: -webkit-box; /* Chrome 4+, Safari 3.1, iOS Safari 3.2+ */ display: -moz-box; /* Firefox 17- ...
- bt设置指定的ip地址
auto eth0 iface eth0 inet staticaddress 192.168.1.112 IP地址netmask 255.255.255.0 子网掩码network 192.168. ...
- IE8提速经验
给人写了个web程序,其中detail页要加载不少东西,所以耗时略长.因为bootstrap的原因,我要求用户使用chrome; 而chrome出了名的快,所以也基本没觉得什么. 后来用户因为别的原因 ...
- 洛谷 P1413 坚果保龄球
题目描述 PVZ这款游戏中,有一种坚果保龄球.zombie从地图右侧不断出现,向左走,玩家需要从左侧滚动坚果来碾死他们. 我们可以认为地图是一个行数为6,列数为60的棋盘.zombie出现的那一秒站在 ...
- Hadoop 安装过程中出现的问题
1.hadoop-daemon.sh start namenode 启动失败 查看hadoop/logs 下面的日志 出现 2017-04-11 15:35:13,860 WARN org.apach ...
- 深入理解Java的整型类型:如何实现2+2=5?
先看下这段神奇的Java代码: public static void main(String[] args) throws Exception { doSomethingMagic(); System ...
- 植物大战僵尸游戏的开发(python)
装备东西: 搭建好python环境, 四张图片,(背景图片,炮弹图片,僵尸图片,豌豆图片),就ok了 没有安装pygame的需要进行安装 pip install pygame 参考视频 # 植物大 ...
- Js 之获取QueryString的几种方法
一.正则匹配 function getQueryString(name) { var reg = new RegExp('(^|&)' + name + '=([^&]*)(& ...