poj 2288 Islands and Bridges

题意: 给你一个双向连通图,求 获得权值最大 的 哈密顿通路的 权值 和 这个权值对应的数目;

  其中权值计算方法是  列如 ABCD  权值是a+b+c+d+ab+bc+cd 如果 A,B,C  和B,C,D 可构成三角形分别加上abc,bcd;

这个题 和poj 3311  很相像: 那个需要记录一个最后到达的地方   这个需要记录俩个罢了

DP[i][a][b]其中 i  二进制 中1表示这个点走过了   最后走的的 的是b>>a

因为对于已经走过了{1,2,3,4,,5,6,..,N}  为了推出下一次走到X 我们要获得权值 只和最后走的俩个点有关?

给出代码::

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cmath>
 4 #include <cstdlib>
 5 #include <cstring>
 6 #include <iostream>
 7 using namespace std;
 8 long long  dp[1<<13][13][13];
 9 long long  num[1<<13][13][13];
10 int n;
11 int val[13];
12 bool Map[13][13];
13 void solve()
14 {
15     for(int i=0;i<(1<<n);i++)for(int a=0;a<n;a++)for(int b=0;b<n;b++)
16     {
17         if(!Map[a][b])continue;
18         if(a==b)continue;
19         if((i&(1<<a))==0||(i&(1<<b))==0)continue;
20         if(i==((1<<a)+(1<<b)))
21         {
22             dp[i][a][b]=val[a]+val[b]+val[a]*val[b];
23             num[i][a][b]=1;
24             continue;
25         }
26         else
27         {
28             for(int c=0;c<n;c++)
29             {
30                 if(c==a||c==b||(!Map[b][c])) continue;
31                 if((i&(1<<c))==0) continue;
32                 long long  tmp;
33                 if(dp[i^(1<<a)][b][c]==-1)continue;
34                 if(Map[a][c]) tmp=val[a]+val[a]*val[b]+val[a]*val[b]*val[c];
35                 else tmp=val[a]+val[a]*val[b];
36                 if(dp[i][a][b]<dp[i^(1<<a)][b][c]+tmp)
37                 {
38                     num[i][a][b]=num[i^(1<<a)][b][c];
39                     dp[i][a][b]=dp[i^(1<<a)][b][c]+tmp;
40                 }
41                 else if(dp[i][a][b]==dp[i^(1<<a)][b][c]+tmp)
42                     num[i][a][b]+=num[i^(1<<a)][b][c];
43             }
44         }
45     }
46     long long  ans=-1;
47     long long  ans_num=0;
48     for(int b=0;b<n;b++) for(int c=0;c<n;c++)
49     {
50         if(ans<dp[(1<<n)-1][b][c])
51         {
52             ans=dp[(1<<n)-1][b][c];
53             ans_num=num[(1<<n)-1][b][c];
54         }
55         else if(ans==dp[(1<<n)-1][b][c])
56             ans_num+=num[(1<<n)-1][b][c];
57
58     }
59     if(ans==-1) printf("0 0\n");
60     else printf("%lld %lld\n",ans,ans_num/2);
61 }
62 int main()
63 {
64     int q;
65     scanf("%d",&q);
66     while(q--)
67     {
68         memset(Map,false,sizeof(Map));
69         memset(dp,-1,sizeof(dp));
70         memset(num,0,sizeof(num));
71         int m;
72         scanf("%d%d",&n,&m);
73         for(int i=0;i<n;i++)scanf("%d",&val[i]);
74         for(int i=1;i<=m;i++)
75         {
76             int a,b;
77             scanf("%d%d",&a,&b);
78             a--,b--;
79             Map[a][b]=Map[b][a]=true;
80         }
81         if(n==1) printf("%d 1\n",val[0]);
82         else
83         solve();
84     }
85     return 0;
86 }

poj 2288 Islands and Bridges

时间: 2024-10-27 13:17:36

poj 2288 Islands and Bridges的相关文章

POJ 2288 Islands and Bridges 哈密尔顿路 状态压缩DP

找最长的其实是很裸的状态压缩DP,棘手的地方是要统计数量,其实只要再来一个数组存就好. 不过代码比较长,细节要注意的地方毕较多,wa了很多发,还是要仔细啊 用递推和记忆化搜索分别写了一遍 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <

POJ 2288 Islands and Bridges(状压dp)

Language: Default Islands and Bridges Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 9312   Accepted: 2424 Description Given a map of islands and bridges that connect these islands, a Hamilton path, as we all know, is a path along the b

poj 2288 Islands and Bridges ——状压DP

题目:http://poj.org/problem?id=2288 状压挺明显的: 一开始写了(记忆化)搜索,但一直T: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; int const inf=0x3f3f3f3f; int T,n,m,v[15]; ll ans,cnt

【以前的空间】poj 2288 Islands and Bridges

一个不错的题解 : http://blog.csdn.net/accry/article/details/6607703 这是一道状态压缩.每个点有一个值,我们最后要求一个最值sum.sum由三部分组成:①每个点的值②每个点与他相邻的点的乘积③如果存在三个点成环,还要加上这三个点的值的乘积. 状态转移方程为:dp[i][j][k]=max(dp[i,j,k],dp[i'][k][l]+temp) j表示当前点,k表示上一个点,l表示上上一个点. 其中i,i'表示可以走到i点的状态,temp表示这

POJ 2288 Islands And Bridges 状态压缩dp+哈密顿回路

题意:n个点 m条边的图,路径价值定义为相邻点乘积,若路路径c[i-1]c[i]c[i+1]中c[i-1]-c[i+1]有边 则价值加上三点乘积找到价值最大的哈密顿回路,和相应的方法数n<=13.暴力dfs O(13!) TLE 由于n<13 经典的状态压缩dp [状态] [当前点位置 ][前一点位置] 注意上一个状态必须合法才能进行转移设状态dp[s][i][j] 当前状态为s,当前点为i上一个点为j的最大价值, ans=max(dp[(1<<n)-1][i])dp[s][i][

POJ 2288 Islands and Bridges(状压DP)题解

题意:n个点,m有向边,w[i]表示i的价值,求价值最大的哈密顿图(只经过所有点一次).价值为:所有点的w之和,加上,每条边的价值 = w[i] * w[j],加上,如果连续的三个点相互连接的价值 = w[i] * w[j] * w[k].n <= 13. 思路:dp[state][i][j]表示state状态下,最后两个为i,j. 代码: #include<cmath> #include<set> #include<map> #include<queue&

poj 2288 Islands and Bridges_状态压缩dp_哈密尔顿回路问题

题目链接 题目描写叙述:哈密尔顿路问题.n个点,每个点有权值,设哈密尔顿路为 C1C2...Cn,Ci的权值为Vi,一条哈密尔顿路的值分为三部分计算: 1.每个点的权值之和2.对于图中的每一条CiCi+1,加上Vi*Vi+1 3.对于路径中的连续三个点:CiCi+1Ci+2,若在图中,三点构成三角形,则要加上Vi*Vi+1*Vi+2 求一条汉密尔顿路能够获得的最大值,而且还要输出有多少条这种哈密尔顿路. 这道题的状态感觉不是非常难想,由于依据一般的哈密尔顿路问题,首先想到的是设计二维状态,dp[

poj 2280 Islands and Bridges 哈密尔顿路 状压dp

题目链接 题意 给定一个\(N\)个点的无向图,求一条哈密尔顿路径\(C_1C_2...C_n\),使其\(value\)最大. \(value\)的计算方式如下:\[\begin{aligned}value&=\sum_{i=1}^{n}C_i\\&+\sum_{i=1}^{n-1}C_i*C_{i+1}\\&+\sum_{i=1}^{n-2}C_i*C_{i+1}*C_{i+2}[(C_i,C_{i+2})is\ an\ edge\ in\ the\ graph]\end{al

poj2288(Islands and Bridges) 状压DP

题目链接:http://poj.org/problem?id=2288 题意:每个点有一个权值Vi,找一条哈密顿路径,路径的权值来自三条:1 路径上的Vi之和 2 所有相邻点对ij的Vi*Vj之和 3 相邻连续三点i,j,k(并且三点要构成三角形)Vi*Vj*Vk之和. 解法:dp[st][i][j]表示从j走到i并且剩下集合st没有走的最大权值.关于路径书,在转移的时候顺便计算即可:这道题令自己恶心了好久,最后原因是自己犯了一个严重错误,题目读错了,没有读到Vi*Vj*Vk要保证ijk能够构成