题目大意:

有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解决的更多相关文章

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

    题意:给你一个图和每个点的价值,边权值为连接两点权值的积,走哈密顿通路,若到达的点和上上个点相连则价值加三点乘积,求哈密顿通路的最大价值,和最大价值哈密顿通路的条数. 分析:开始看这个题很吓人,但想想 ...

  2. UVA1292-----Strategic game-----树形DP解决树上的最小点覆盖问题

    本文出自:http://blog.csdn.net/dr5459 题目地址: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&a ...

  3. POJ.3624 Charm Bracelet(DP 01背包)

    POJ.3624 Charm Bracelet(DP 01背包) 题意分析 裸01背包 代码总览 #include <iostream> #include <cstdio> # ...

  4. 7-4 汉密尔顿回路(25 分) 【STL】

    7-4 汉密尔顿回路(25 分) 著名的"汉密尔顿(Hamilton)回路问题"是要找一个能遍历图中所有顶点的简单回路(即每个顶点只访问 1 次).本题就要求你判断任一给定的回路是 ...

  5. POJ 1390 Blocks (区间DP) 题解

    题意 t组数据,每组数据有n个方块,给出它们的颜色,每次消去的得分为相同颜色块个数的平方(要求连续),求最大得分. 首先看到这题我们发现我们要把大块尽可能放在一起才会有最大收益,我们要将相同颜色块合在 ...

  6. POJ 2995 Brackets 区间DP

    POJ 2995 Brackets 区间DP 题意 大意:给你一个字符串,询问这个字符串满足要求的有多少,()和[]都是一个匹配.需要注意的是这里的匹配规则. 解题思路 区间DP,开始自己没想到是区间 ...

  7. 蓝桥杯 试题 算法提高 宰羊 DP解决

    问题描述 炫炫回了内蒙,肯定要吃羊肉啦,所有他家要宰羊吃. 炫炫家有N只羊,羊圈排成一排,标号1~N.炫炫每天吃掉一只羊(这食量!其实是放生啦),吃掉的羊的邻居会以为它被放生了,然后又会告诉他们的邻居 ...

  8. 蓝桥杯 试题 历届试题 对局匹配 DP解决

    问题描述 小明喜欢在一个围棋网站上找别人在线对弈.这个网站上所有注册用户都有一个积分,代表他的围棋水平. 小明发现网站的自动对局系统在匹配对手时,只会将积分差恰好是K的两名用户匹配在一起.如果两人分差 ...

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

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

随机推荐

  1. 基于CentOS 7.2个人网盘的实现

    首先使用YUM安装依赖环境: [root@sishen ~]#yum install python python-setuptools python-imaging python-ldap pytho ...

  2. Oracle历史版本及oracle相关软件下载地址

    网站:https://edelivery.oracle.com/ 可能需要注册个账号!!!(账号注册登录自己折腾下就好了) 下载数据库或者oracle的相关软件的话,如下 选择对应的下载即可!

  3. Windows下Apache应用环境塔建安全设置(目录权限设置)

    目的:为Apache,php配置受限制的用户权限.保护系统安全.需要的朋友可以参考下. 环境配置情况: apache安装目录:d:\www-s\apache php目录:d:\www-s\php5 m ...

  4. Design Patterns Uncovered: The Chain Of Responsibility Pattern

    Chain of Responsibility in the Real World The idea of the Chain Of Responsibility is that it avoids ...

  5. 23中java设计模式(1)-- 策略模式

    近来不太忙,就打算抽空看下源码补充一下知识,当我看了之后我发现看源码的关键是要弄清楚类之家的关系以及为何要这样的关系,否则如果只看具体的代码那不如去学习会儿算法. 于是就打算从设计模式入手,边学习边记 ...

  6. VC++编译出错:LNK1123: 转换到 COFF 期间失败: 文件无效或损坏

    解决方法: 1.搜索C盘下的cvtres.exe,结果得到类似这样的列表: C:\Program Files\Microsoft Visual Studio 10.0\VC\bin C:\Window ...

  7. spark性能优化-JVM虚拟机垃圾回收调优

    1 2 3 4

  8. CCS3超长文字显示省略号的方法

    需求:当文本长度溢出包含元素时以省略号结尾 CSS3实现方法: #MyDIV{overflow:hidden;text-overflow:ellipsis;} 示例:<!DOCTYPE html ...

  9. ZGC,一个超乎想象的垃圾收集器

    Z Garbage Collector,即ZGC,是一个可伸缩的.低延迟的垃圾收集器,主要为了满足如下目标进行设计: 停顿时间不会超过10ms 停顿时间不会随着堆的增大而增大(不管多大的堆都能保持在1 ...

  10. 富通天下(W 笔试)

    纸质算法题目 1.给你一个字符串,找出其中第一个只出现过一次的字符及其位置 正解:一层for循环,循环按序取出字符串中的单个字符,循环体内部使用String类的indexOf(),从当前字符下标往后搜 ...