POJ 2288 Islands and Bridges(状压dp)
Posted 谦谦君子,陌上其华
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 2288 Islands and Bridges(状压dp)相关的知识,希望对你有一定的参考价值。
http://poj.org/problem?id=2288
题意:
有n个岛屿,每个岛屿有一个权值V,一条哈密顿路径C1,C2,...Cn的值为3部分之和:
第1部分,将路径中每个岛屿的权值累加起来;第2部分,对路径中的每条边(Ci,Ci+1),将成绩Vi×Vi+1累加起来;第3部分,当路径中连续的3个岛屿Ci、Ci+1和Ci+2形成一个三角形,即在岛屿Ci和Ci+2之间有一座桥,则把乘积Vi×Vi+1×Vi+2累加起来。
寻找权值最大的哈密顿路径和其路径数。
思路:
用d【status】【i】【j】表示当前状态为status,并且最后两个顶点分别为 i 和 j 时的最大权值,同理,ways【status】【i】【j】表示此时对应的路径的数量。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<sstream> 6 #include<vector> 7 #include<stack> 8 #include<queue> 9 #include<cmath> 10 #include<map> 11 #include<set> 12 using namespace std; 13 typedef long long ll; 14 typedef pair<int,int> pll; 15 const int INF = 0x3f3f3f3f; 16 const int maxn = 1000 + 5; 17 18 int n, m; 19 20 int val[13]; 21 int g[13][13]; 22 ll d[1<<13][13][13]; 23 ll ways[1<<13][13][13]; 24 25 int main() 26 { 27 //freopen("in.txt","r",stdin); 28 int T; 29 scanf("%d",&T); 30 while(T--) 31 { 32 memset(g,0,sizeof(g)); 33 memset(d,-1,sizeof(d)); 34 memset(ways,0,sizeof(ways)); 35 36 scanf("%d%d",&n,&m); 37 for(int i=0;i<n;i++) scanf("%d",&val[i]); 38 for(int i=0;i<m;i++) 39 { 40 int u, v; 41 scanf("%d%d",&u, &v); 42 u--; v--; 43 g[u][v]=g[v][u]=1; 44 //初始化 45 d[(1<<u)|(1<<v)][u][v]=d[(1<<u)|(1<<v)][v][u]=val[u]+val[v]+val[u]*val[v]; 46 ways[(1<<u)|(1<<v)][u][v]=ways[(1<<u)|(1<<v)][v][u]=1; 47 } 48 49 ll maxvalue=-1; 50 ll maxways=0; 51 52 if(n==1) {maxvalue=val[0];maxways=1;} //如果只有一个顶点,则特判 53 54 if(n!=1) 55 for(int s=0;s<(1<<n);s++) 56 { 57 for(int i=0;i<n;i++) 58 { 59 if(s&(1<<i)) 60 for(int j=0;j<n;j++) 61 { 62 if((i!=j) && (s&(1<<j)) &&d[s][i][j]>-1) 63 { 64 for(int k=0;k<n;k++) //枚举新加入的顶点 65 { 66 if(!(s&(1<<k)) && g[j][k]) 67 { 68 int nextstatus=s|(1<<k); 69 ll tmp = d[s][i][j]+val[k]+val[j]*val[k]; 70 if(g[i][k]) //如果Ci和Ci+2之间存在桥 71 tmp+=val[i]*val[j]*val[k]; 72 73 if(d[nextstatus][j][k]==tmp) 74 { 75 ways[nextstatus][j][k]+=ways[s][i][j]; 76 } 77 else if(d[nextstatus][j][k]<tmp) 78 { 79 d[nextstatus][j][k]=tmp; 80 ways[nextstatus][j][k]=ways[s][i][j]; 81 } 82 } 83 } 84 } 85 } 86 } 87 } 88 89 int s=(1<<n)-1; 90 if(n!=1) 91 for(int i=0;i<n;i++) 92 { 93 for(int j=0;j<n;j++) 94 { 95 if(g[i][j]==0) continue; 96 if(d[s][i][j]>maxvalue) 97 { 98 maxvalue=d[s][i][j]; 99 maxways=ways[s][i][j]; 100 } 101 else if(d[s][i][j]==maxvalue) 102 maxways+=ways[s][i][j]; 103 } 104 } 105 if(n!=1) maxways/=2; //因为正向和逆向是一样的,所以这里除2 106 if(maxvalue==-1) puts("0 0"); 107 else printf("%lld %lld\n",maxvalue,maxways); 108 } 109 return 0; 110 }
以上是关于POJ 2288 Islands and Bridges(状压dp)的主要内容,如果未能解决你的问题,请参考以下文章
POJ2288 Islands and Bridges (DP)
poj 2288 Islands and Bridges ——状压DP
POJ 2288 Islands and Bridges(状压dp)
以前的空间poj 2288 Islands and Bridges