• POJ2288 Islands and Bridges (状压dp)


    本题就是经典的哈密顿回路,但是有一个附加条件,就是如果有三个相邻,那么可以附加值

    这样我们就可以枚举4维,判断条件后再加上

    本题有几个坑点

    1.爆int

    2.有可能不存在这样的路

    3.题目定义的路是不重复的,所以要/2

    4.本题应该先预处理两个的情况,再用他推大的情况,我们普通的是用小的来维护现在,而这道题用现在来维护以后

    其实可以不用预处理,在循环内判断,但是预处理比较简单

    5.我们设计的状态为f[i][j][k],当前集合为i,在j,由k跳过来

    6.特判一个点的情况

    #include<algorithm>
    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<string> 
    #include<set>
    #include<map>
    #include<queue>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=14;
    const int inf=0x3f3f3f3f;
    ll f[1<<N][N][N];
    ll num[1<<N][N][N];
    int n,m;
    int g[N][N];
    int w[N]; 
    int main(){
        int i,j,k;
        int q;
        cin>>q;
        while(q--){
            memset(num,0,sizeof num);
            memset(g,0,sizeof g);
            cin>>n>>m;
        for(i=0;i<n;i++)
        cin>>w[i];
        for(i=1;i<=m;i++){
            int u,v;
            cin>>u>>v;
            g[u-1][v-1]=1;
            g[v-1][u-1]=1;
        }
        if(n==1){
            cout<<w[0]<<" 1"<<endl;
            continue;
        }
        memset(f,-1,sizeof f);
        for(i=0;i<n;i++){
            for(j=0;j<n;j++){
                if(g[i][j]){
                    f[1<<i|1<<j][i][j]=w[i]+w[j]+w[i]*w[j];
                    num[1<<i|1<<j][i][j]=1;
                }
            }
        }
        int l;
        for(i=3;i<1<<n;i++){
            for(j=0;j<n;j++){
                if(!(i>>j&1))
                continue;
                for(k=0;k<n;k++){
                    if(k==j||!(i>>k&1))
                    continue;
                    if(f[i][j][k]==-1) 
                    continue;
                    for(l=0;l<n;l++){
                        if(i>>l&1||!g[j][l])
                        continue;
                        int r=i|(1<<l);
                        ll tmp=f[i][j][k]+w[j]*w[l]+w[l];
                        if(g[k][l])
                        tmp+=w[k]*w[j]*w[l];
                        if(f[r][l][j]<tmp){
                            f[r][l][j]=tmp;
                            num[r][l][j]=num[i][j][k];
                        }            
                        else if(f[r][l][j]==tmp){
                            num[r][l][j]+=num[i][j][k];
                        }
                    }                
                }
            } 
        }
        ll ans=0;
        ll res=0;
        for(i=0;i<n;i++){
            for(j=0;j<n;j++){
                if(f[(1<<n)-1][i][j]>ans){
                    ans=f[(1<<n)-1][i][j];
                    res=num[(1<<n)-1][i][j];
                }
                else if(f[(1<<n)-1][i][j]==ans){
                    res+=num[(1<<n)-1][i][j];
                }
            }
        }
        if(!ans)
        cout<<"0 0"<<endl;
        else
        cout<<ans<<" "<<res/2<<endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    微信支付系列(2)——jsapi支付源码解析
    微信支付系列(1)
    java创建文件和目录
    在线文档预览方案-office web apps
    必要的思考
    做WEB开发的时候,前端与后端我们应该要注意哪些细节,哪些容易出现的漏洞?
    使用MVVM框架时,如何处理在页面动态渲染完之后需要发生的事件呢?
    系统间通信(10)——RPC的基本概念
    系统间通信(9)——通信管理与RMI 下篇
    系统间通信(8)——通信管理与RMI 上篇
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12391705.html
Copyright © 2020-2023  润新知