zoukankan      html  css  js  c++  java
  • poj 2288 Islands and Bridges——状压dp(哈密尔顿回路)

    题目:http://poj.org/problem?id=2288

    不知为什么记忆化搜索就是WA得不得了!

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define ll long long
    using namespace std;
    const int N=20,Lm=(1<<13)+5;
    int q,n,m,lm,v[N];
    ll ans,prn,dp[Lm][N][N],f[Lm][N][N];
    bool b[N][N];
    ll dfs(int S,int x,int px)
    {
        if(dp[S][x][px]!=-1)return dp[S][x][px];
        if(S==lm){f[S][x][px]=1;return dp[S][x][px]=0;}
        for(int i=1;i<=n;i++)
            if(b[x][i]&&(S&(1<<(i-1)))==0)
            {
                int D=(S|(1<<(i-1)));
                ll w=dfs(D,i,x)+v[i]+v[x]*v[i]+(b[px][i]?v[px]*v[x]*v[i]:0);
                if(w>dp[S][x][px])
                    dp[S][x][px]=w,f[S][x][px]=f[D][i][x];
                else if(w==dp[S][x][px])
                    f[S][x][px]+=f[D][i][x];
            }
        return dp[S][x][px];
    }
    int main()
    {
        scanf("%d",&q);
        while(q--)
        {
            memset(b,0,sizeof b);
            scanf("%d%d",&n,&m);lm=(1<<n)-1;
            for(int i=1;i<=n;i++)scanf("%d",&v[i]);
            int x,y;
            for(int i=1;i<=m;i++)
            {
                scanf("%d%d",&x,&y);b[x][y]=1;b[y][x]=1;
            }
            if(n==1){printf("%d 1
    ",v[1]);continue;}//
            memset(dp,-1,sizeof dp);memset(f,0,sizeof f);
            ans=-1;prn=0;
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    if(b[i][j])
                    {
                        int D=((1<<(i-1))|(1<<(j-1)));//注意括号! 
                        ll w=dfs(D,i,j)+v[i]*v[j]+v[i]+v[j];
                        if(w>ans)ans=w,prn=f[D][i][j];
                        else if(w==ans)prn+=f[D][i][j]; 
                    }
            printf("%I64d %I64d
    ",prn?ans:0,prn>>1);//
        }
        return 0;
    }
    View Code

    改成刷表就可A了。注意初始化一遍,然后开始dp,而不是一边初始化一边dp很多次。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int N=20,Lm=(1<<13)+5;
    int T,n,m,c[N],lm;
    ll dp[Lm][N][N],f[Lm][N][N],ans,prn;
    bool b[N][N];
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            memset(b,0,sizeof b);
            scanf("%d%d",&n,&m);lm=(1<<n)-1;
            for(int i=1;i<=n;i++)scanf("%d",&c[i]);
            int x,y;
            while(m--)
            {
                scanf("%d%d",&x,&y);
                b[x][y]=b[y][x]=1;
            }
            if(n==1){printf("%d 1
    ",c[1]);continue;}
            memset(dp,-1,sizeof dp);memset(f,0,sizeof f);
            for(int u=1;u<=n;u++) for(int v=1;v<=n;v++) if(b[u][v])
            {
                int s=((1<<(u-1))|(1<<(v-1)));
                dp[s][u][v]=c[u]+c[v]+c[u]*c[v];
                f[s][u][v]=1;
            }
            for(int s=3;s<=lm;s++)
                for(int i=1;i<=n;i++) if(s&(1<<(i-1)))
                    for(int j=1;j<=n;j++) if(dp[s][i][j]!=-1)
                        for(int k=1;k<=n;k++) if(b[i][k]&&!(s&(1<<(k-1))))
                        {
                            int d=(s|(1<<(k-1)));
                            ll w=dp[s][i][j]+c[k]+c[i]*c[k]+(b[j][k]?c[i]*c[j]*c[k]:0);
                            if(dp[d][k][i]<w)
                            {
                                dp[d][k][i]=w;
                                f[d][k][i]=f[s][i][j];
                            }
                            else if(dp[d][k][i]==w)
                                f[d][k][i]+=f[s][i][j];
                        }
            ans=-1;prn=0;//因为有"prn?" 
            for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(dp[lm][i][j]!=-1)
                if(dp[lm][i][j]>ans)ans=dp[lm][i][j],prn=f[lm][i][j];
                else if(dp[lm][i][j]==ans)prn+=f[lm][i][j];
            printf("%I64d %I64d
    ",prn?ans:0,prn>>1);
        }
        return 0;
    }
  • 相关阅读:
    推荐影视
    《算法设计》一、引言:某些典型的问题
    使用google地图API
    Python导入不同文件夹下模块
    Pycharm之远程编程
    linux之scp
    Photoshop脚本之jpg转换成eps
    win7重新安装win7
    查看修改swap空间大小
    用 EasyBCD 在 Win7/8 中硬盘安装 Ubuntu
  • 原文地址:https://www.cnblogs.com/Narh/p/9379133.html
Copyright © 2011-2022 走看看