题目大意:

有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. DNS练习之反向解析

    环境同正向解析一样. 切换到/var/named/chroot/etc目录下: 编辑named.rfc1912.zones文件,在末尾添加如下内容: [root@sishen63 etc]# vim ...

  2. ubuntu安装mysql多实例

    想要尝试mysql的读写分离,在云上安装完mysql之后突然想到一个问题:我本机是没有公网IP的. 开始尝试在唯一一台云服务器上安装多个mysql实例. 主要步骤: 1.新建MySQL目录 (1):新 ...

  3. php 缓存工具类 实现网页缓存

    php 缓存工具类 实现网页缓存 php程序在抵抗大流量访问的时候动态网站往往都是难以招架,所以要引入缓存机制,一般情况下有两种类型缓存 一.文件缓存 二.数据查询结果缓存,使用内存来实现高速缓存 本 ...

  4. This is such a crock of shit—From Scent of a woman

    - Mr. Slade. - This is such a crock of shit! - Mr. Trask. - Please watch your language, Mr. Slade. Y ...

  5. Linux安装技巧--安装Uuntu与windows8/10共存

    1.准备安装双系统所需工具. 系统: Linux有众多的衍生版本,选择一个自己喜欢的版本下载,建议新手上ubuntu吧,中文教程较多,出了问题容易解决,等到熟悉了再用其他的也行,新手的话ubuntu也 ...

  6. Debian9镜像安装问题

    Debian9下载地址 https://www.debian.org/distrib/ Debian9有三个镜像文件 第一个包含系统2.3两个主要是一些软件的安装包只需下载第一个安装系统即可 默认安装 ...

  7. vue项目中常用的一些公共方法

    //校验手机号码 export function isSpecialPhone(num) { return /^1[2,3,4,5,7,8]\d{9}$/.test(num) } //校验中英文姓名 ...

  8. 8.3.3 快速系统调用 —— XP SP3上SystemCallStub的奇怪问题

    依书上的例子,ReadFile()函数会调用ntdll!NtReadFile(),后者将服务号放到eax之中,然后调用SharedUserData!SystemCallStub(),由此函数执行sys ...

  9. HTML5应用 + Cordova = 平台相关的混合应用

    Jerry之前的一篇文章 SAP Fiori应用的三种部署方式 曾经提到SAP Fiori应用的三种部署方式: On Premise环境下以ABAP BSP应用作为Fiori应用部署和运行的载体 部署 ...

  10. JS 冒泡事件顺序

    参考:https://www.cnblogs.com/diaoyan/p/5630014.html