poj 2288 Islands and Bridges ——状压DP

Posted zinn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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,f[1<<13];
bool mp[15][15];
void dfs(int z,int x,int y,ll w)
{
    if(w<f[z])return;
    f[z]=w;
    if(z==(1<<n)-1)
    {
        if(w>ans)ans=w,cnt=1;
        else if(w==ans)cnt++;
        return;
    }
    for(int i=1;i<=n;i++)
        if((z&(1<<(i-1)))==0)
            dfs(z|(1<<(i-1)),y,i,w+v[i]+v[y]*v[i]+(mp[x][i]?v[x]*v[y]*v[i]:0));
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        memset(f,0,sizeof f);
        memset(mp,0,sizeof mp); 
        ans=-inf; cnt=0;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&v[i]);
        for(int i=1,x,y;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            mp[x][y]=1; mp[y][x]=1;
        }
        dfs(0,0,0,0);
        if(cnt==0)printf("0 0
");
        else printf("%lld %lld
",ans,cnt/2);
    }
    return 0;
}

于是改成刷表,注意点细节就行了。

代码如下:

#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,f[1<<13|1][15][15],s[1<<13|1][15][15];
bool mp[15][15];
void dp()
{
    memset(f,-1,sizeof f);
    memset(s,0,sizeof s);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)    if(mp[i][j])
        {    
            int p=((1<<(i-1))|(1<<(j-1)));
            f[p][i][j]=v[i]+v[j]+v[i]*v[j]; s[p][i][j]=1;
        }
    for(int p=3;p<(1<<n);p++)
        for(int i=1;i<=n;i++)    if(!(p&(1<<(i-1))))
            for(int j=1;j<=n;j++)    if(p&(1<<(j-1)))
                for(int k=1;k<=n;k++)     if((p&(1<<(k-1)))&&j!=k&&mp[i][k]&&f[p][j][k]!=-1)
                {
                    ll tmp=f[p][j][k]+v[i]+v[k]*v[i]+(mp[j][i]?v[j]*v[k]*v[i]:0);
                    int tp=(p|(1<<(i-1)));
                    if(tmp>f[tp][k][i]) f[tp][k][i]=tmp,s[tp][k][i]=s[p][j][k];
                    else if(tmp==f[tp][k][i])s[tp][k][i]+=s[p][j][k];
                }
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        memset(mp,0,sizeof mp); 
        ans=-inf; cnt=0;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&v[i]);
        for(int i=1,x,y;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            mp[x][y]=1; mp[y][x]=1;
        }
        if(n==1){printf("%d %d
",v[1],1); continue;}//
        dp(); int mx=(1<<n)-1;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)    if(i!=j)
            {
                if(f[mx][i][j]==ans)cnt+=s[mx][i][j];
                else if(f[mx][i][j]>ans)ans=f[mx][i][j],cnt=s[mx][i][j];
            }
        if(cnt==0)printf("0 0
");//
        else printf("%I64d %I64d
",ans,cnt/2);//
    }
    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+哈密顿回路