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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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][j]= S=s^(1<<(i-1))&&dp[S][j][k]状态合法 max(dp[S][j][k]+v[j]*v[k]+v[i]*v[j]*v[k] (c[k],c[i]存在边))
O(2^13*13^3)

 

 

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
const int N=1<<14;
ll n,m,v[15],g[15][15];
ll dp[N][15][15],path[N][15][15];
int main()
{
	int q;
	scanf("%d",&q);
	while(q--)
	{
		memset(dp,-1,sizeof(dp));
		memset(g,0,sizeof(g));
		memset(path,0,sizeof(path));
		scanf("%I64d%I64d",&n,&m);
		for(int i=0;i<n;i++)
			scanf("%I64d",&v[i]);
		int u,V;
		while(m--)
		{
			scanf("%d%d",&u,&V);
			u--,V--;
			g[u][V]=g[V][u]=1;
		}
		if(n==1)
		{
			cout<<v[0]<<‘ ‘<<1<<endl;
			continue;
		}
		//3?ê??ˉ?àáúá?μ??·??dp?μ 
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
			{
				if(i==j)	continue;
				if(g[i][j])
				{
					dp[(1<<i)+(1<<j)][i][j]=v[i]+v[j]+v[i]*v[j];
					path[(1<<i)+(1<<j)][i][j]=1;
				}
			}
		}
		for(int s=0;s<(1<<n);s++)
		{
			for(int i=0;i<n;i++)
			{
				if(s&(1<<i)==0)	continue;
				for(int j=0;j<n;j++)
				{
					if(j==i||g[i][j]==0)	continue;
					if((s&(1<<j))==0)	continue;
					for(int k=0;k<n;k++)
					{
						if(j==k||((s&(1<<k))==0)||g[j][k]==0)	continue;
						int add=v[i]+v[i]*v[j];
						if(g[i][k])
							add+=v[i]*v[j]*v[k];
						int S=s^(1<<i);
						if(dp[S][j][k]==-1)	continue;//?°ò???×′ì?òao?·¨ 
						
						int tmp=dp[S][j][k]+add;
						if(tmp>dp[s][i][j])
							dp[s][i][j]=tmp,path[s][i][j]=path[S][j][k];
						else if(tmp==dp[s][i][j])
							path[s][i][j]+=path[S][j][k];
					}
				}
			}
		}
		ll ans=-1,cnt=0;
		ll s=(1<<n)-1;
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
			{
				if(i==j)	continue;
				if(ans<dp[s][i][j])
					ans=dp[s][i][j],cnt=path[s][i][j];
				else if(ans==dp[s][i][j])
					cnt+=path[s][i][j];
			}	
		}	
		if(ans==-1)
			ans=0,cnt=0;	
		cout<<ans<<‘ ‘<<cnt/2<<endl;
	}
	return 0;
}

  

以上是关于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

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

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