• 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;
    }
  • 相关阅读:
    TypeError: run() missing 2 required positional arguments: 'rerun' and 'save_last_run'
    在wsl的ubuntu上安装vcpkg
    vscode + WSL +Ubuntu编程解决方案
    clion debug模式带参数运行程序
    关于jdk1.7之后String的intern方法的一点理解
    关于java中split的坑
    关于向HashMap存放数据出现顺序混乱的问题
    oracle外键禁用
    oracle复杂查询(二)
    oracle复杂查询(一)
  • 原文地址:https://www.cnblogs.com/Zinn/p/9367593.html
Copyright © 2020-2023  润新知