题意:

  给一个无向图,n个点m条边,每个点有点权,要求找到一条哈密顿路径,使得该路径的f(path)值最大。输出f值,若有多条最大f值的路径,输出路径数量。

  f值由如下3点累加而来:

  (1)所有点权之和。

  (2)路径上相邻两点的点权之积。

  (3)路径上如果有连续的3个点是一个三角形(即3点成环),则累加三点的点权之积。

思路:

  根据f值的计算方式,第一项基本是不会变的,其他两项与路径有关。由于需要计算第3点,所以状态还需要记录每个状态的最后两个点(有序的),来判断是否为三角形。那么状态表示为[哪些点浏览过][倒数第2个点][末节点],如果是在刚开始,只有1个点,那么第二维就是0就行了。路径数是根据DP的过程来计算的,开一个和状态数一样的数组保存即可。

  注意点:路径统计要小心,图可能不连通,可能只有1个点,路径数可能爆LL?

 //#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <deque>
#include <map>
#include <algorithm>
#include <vector>
#include <iostream>
#define pii pair<int,int>
#define INF 0x3f3f3f3f
#define LL long long
#define ULL unsigned long long
using namespace std;
const double PI = acos(-1.0);
const int N=;
int n, w[N];
LL cnt[<<][N][N], dp[<<][N][N],ans, ans2;
bool g[N][N]; void fuck(int s,int i,int k)
{
for(int j=; j<=n; j++) //枚举终点
{
if( (s&(<<j-)) || !g[i][j] ) continue;//已经走过or无路径 LL c=cnt[s][k][i];
LL v=dp[s][k][i]+w[i]*w[j];
if( g[k][j] ) v+=w[k]*w[i]*w[j]; //三角形出现 LL &cc=cnt[s|(<<j-)][i][j];
LL &dd=dp[s|(<<j-)][i][j];
if( dd<=v )
{
if(dd==v) cc+=c;
else cc=c;
dd=v;
}
}
}
void cal()
{
memset(dp,-,sizeof(dp));
memset(cnt,,sizeof(cnt));
ans=-;
ans2=-;
for(int i=; i<=n; i++)
{
dp[<<i-][][i]=;
cnt[<<i-][][i]=;
}
for(int s=; s<(<<n); s++)
{
for(int i=; i<=n; i++) //枚举k->i结尾
{
if( ( s&(<<i-) )== ) continue;
for(int k=; k<=n; k++)
{
if( k>&&(s&(<<k-))== || k==i ) continue;
if( dp[s][k][i]< ) continue;
fuck(s,i,k);
}
}
}
for(int i=; i<=n; i++) //枚举k->i结尾
{
for(int k=; k<=n; k++)
{
if(i==k || dp[(<<n)-][k][i]< ) continue;
if( ans==dp[(<<n)-][k][i] )
ans2+=cnt[(<<n)-][k][i];
else if( ans<dp[(<<n)-][k][i] )
{
ans=dp[(<<n)-][k][i];
ans2=cnt[(<<n)-][k][i];
}
}
}
} int main()
{
//freopen("input.txt","r",stdin);
int m, a, b, t, sum;cin>>t;
while(t--)
{
sum=;
scanf("%d%d",&n,&m);
memset(g,,sizeof(g));
for(int i=; i<=n; i++)
{
scanf("%d",&w[i]);
sum+=w[i];
}
for(int i=; i<m; i++)
{
scanf("%d%d",&a,&b);
g[a][b]=g[b][a]=true;
}
if(n==) printf("%d 1\n", w[]);
else
{
cal();
if(ans<) printf("0 0\n");
else printf("%lld %lld\n", ans+sum, ans2/);
}
}
return ;
}

AC代码

POJ 2288 Islands and Bridges (状压DP,变形)的更多相关文章

  1. poj 2288 Islands and Bridges ——状压DP

    题目:http://poj.org/problem?id=2288 状压挺明显的: 一开始写了(记忆化)搜索,但一直T: #include<iostream> #include<cs ...

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

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

  3. [poj2288] Islands and Bridges (状压dp)

    Description Given a map of islands and bridges that connect these islands, a Hamilton path, as we al ...

  4. POJ 1185 炮兵阵地(状压DP)

    炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 26426   Accepted: 10185 Descriptio ...

  5. POJ 2411 Mondriaan's Dream -- 状压DP

    题目:Mondriaan's Dream 链接:http://poj.org/problem?id=2411 题意:用 1*2 的瓷砖去填 n*m 的地板,问有多少种填法. 思路: 很久很久以前便做过 ...

  6. POJ 2411 Mondriaan's Dream ——状压DP 插头DP

    [题目分析] 用1*2的牌铺满n*m的格子. 刚开始用到动规想写一个n*m*2^m,写了半天才知道会有重复的情况. So Sad. 然后想到数据范围这么小,爆搜好了.于是把每一种状态对应的转移都搜了出 ...

  7. 【POJ 2923】Relocation(状压DP+DP)

    题意是给你n个物品,每次两辆车运,容量分别是c1,c2,求最少运送次数.好像不是很好想,我看了网上的题解才做出来.先用状压DP计算i状态下,第一辆可以运送的重量,用该状态的重量总和-第一辆可以运送的, ...

  8. POJ 1185 炮兵阵地 (状压DP)

    题目链接 题意 : 中文题不详述. 思路 :状压DP,1表示该位置放炮弹,0表示不放.dp[i][j][k],代表第 i 行的状态为k时第i-1行的状态为 j 时放置的最大炮弹数.只是注意判断的时候不 ...

  9. 动态规划晋级——POJ 3254 Corn Fields【状压DP】

    转载请注明出处:http://blog.csdn.net/a1dark 分析:刚开始学状压DP比较困难.多看看就发现其实也没有想象中那么难.这道题由于列数较小.所以将行压缩成二进制来看.首先处理第一行 ...

  10. POJ 1185 炮兵阵地 【状压DP】

    <题目链接> 题目大意: 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平 ...

随机推荐

  1. iwork 文件格式分析

    根据维基百科,到2015年苹果推出的iwork版本 第一章:iwork2008介绍 1.文档结构: 是一个资源合集:压缩格式的(内含文件夹和文件) 在windows下修改iwork的文件后缀为.rar ...

  2. 2-6 Flutter开发环境与Android开发环境设置实操(Windows)

    通常安装完AS后,sdk的目录 C:\Users\wjw\AppData\Local\Android\sdk 如果在这个目录下没有找到sdk的目录的话 Settings里面搜索sdk,找到Androi ...

  3. C++ 定位构造

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://yiluohuanghun.blog.51cto.com/3407300/1258 ...

  4. WPF语言切换,国际化

    winform语言切换在每个窗口下面有一个.resx结尾的资源文件,在上面添加新字符串就好了: WPF语言切换跟winform不一样的地方在于需要自己添加资源文件,并且这个资源文件可以写一个,也可以写 ...

  5. mock测试方法及实践改进

    此文已由作者翟曜授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. mock测试常见的定义为:在测试过程中,对于某些不易构造或不易获取的对象,通过创建虚拟对象的方式来模拟测试的测 ...

  6. poj1191(記憶化搜索)

    題目鏈接:http://poj.org/problem?id=1191 題意:中文題誒- 思路:這道題有幾個關鍵點需要想通,不然會比較難做... 首先,題目給出的標準差公式並不是很好計算,需要給它變下 ...

  7. Hyperledger Fabric (1.0)环境部署 chaincode【转】

    三.测试Fabric 其实我们在前面运行./network_setup.sh up的时候系统已经运行了一个Example02的ChainCode测试,部署上去的ChainCodeName是mycc,所 ...

  8. Noip2016day1 天天爱跑步running

    题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.«天天爱跑步»是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图可以看作一一棵包含 个结点 ...

  9. 字符串split函数

    https://www.cnblogs.com/hjhsysu/p/5700347.html 函数:split() Python中有split()和os.path.split()两个函数,具体作用如下 ...

  10. Codeforces Round #566 (Div. 2) B. Plus from Picture

    链接: https://codeforces.com/contest/1182/problem/B 题意: You have a given picture with size w×h. Determ ...