zoukankan      html  css  js  c++  java
  • POJ 2288 Islands and Bridges 哈密尔顿路 状态压缩DP

    找最长的其实是很裸的状态压缩DP,棘手的地方是要统计数量,其实只要再来一个数组存就好。

    不过代码比较长,细节要注意的地方毕较多,wa了很多发,还是要仔细啊

    用递推和记忆化搜索分别写了一遍

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <climits>
    #include <string>
    #include <iostream>
    #include <map>
    #include <cstdlib>
    #include <list>
    #include <set>
    #include <queue>
    #include <stack>
    
    using namespace std;
    
    typedef long long LL;
    const int maxn = 14;
    const int INF = INT_MAX / 3;
    int n,m,dist[maxn][maxn];
    LL v[maxn];
    LL f[maxn][maxn][1 << 14];
    LL cnt[maxn][maxn][1 << 14];
    
    void solve() {
        memset(f,-1,sizeof(f));
        memset(cnt,0,sizeof(cnt));
        int maxstate = (1 << n) - 1; //init
        for(int i = 0;i < n;i++) {
            for(int j = 0;j < n;j++) if(dist[i][j]) {
                int s = (1 << i) | (1 << j);
                f[i][j][s] = v[i] * v[j] + v[i] + v[j];
                cnt[i][j][s] = 1;
            }
        }
        //dp
        LL ans = 0,ct = 0;
        for(int s = 0;s <= maxstate;s++) {
            for(int i = 0;i < n;i++) if(s & (1 << i)) {
                for(int j = 0;j < n;j++) if(dist[i][j] && (s & (1 << j)) && f[i][j][s] != -1) {
                    for(int k = 0;k < n;k++) if(dist[j][k] && !(s & (1 << k))) {
                        int ns = s | (1 << k);
                        LL &nowstate = f[i][j][s],&nextstate = f[j][k][ns];
                        LL &nowcnt = cnt[i][j][s],&nextcnt = cnt[j][k][ns];
                        LL addv = v[j] * v[k] + v[k];
                        if(dist[i][k]) addv += v[i] * v[j] * v[k];
                        if(nowstate + addv > nextstate) {
                            nextstate = nowstate + addv;
                            nextcnt = nowcnt;
                        }
                        else if(nowstate + addv == nextstate) {
                            nextcnt += nowcnt;
                        }
                    }
                    if(s == maxstate) {
                        if(f[i][j][s] > ans) {
                            ans = f[i][j][s];
                            ct = cnt[i][j][s];
                        }
                        else if(f[i][j][s] == ans) {
                            ct += cnt[i][j][s];
                        }
                    }
                }
            }
        }
        if(ans == 0) cout << "0 0" << endl;
        else cout << ans << " " << ct / 2 <<  endl;
    }
    
    int main() {
        //freopen("in.txt","r",stdin);
        int T; scanf("%d",&T);
        while(T--) {
            memset(dist,0,sizeof(dist));
            scanf("%d%d",&n,&m);
            for(int i = 0;i < n;i++) cin >> v[i];
            for(int i = 0;i < m;i++) {
                int a,b; cin >> a >> b;
                a--; b--;
                dist[a][b] = dist[b][a] = 1;
            }
            if(n == 1) cout << v[0] << " " << 1 << endl;
            else solve();
        }
        return 0;
    }
    

      

      1 #include <cstdio>
      2 #include <sstream>
      3 #include <fstream>
      4 #include <cstring>
      5 #include <iostream>
      6 #include <algorithm>
      7 #include <map>
      8 #include <cctype>
      9 #include <ctime>
     10 #include <set>
     11 #include <climits>
     12 #include <vector>
     13 #include <queue>
     14 #include <stack>
     15 #include <cstdlib>
     16 #include <cmath>
     17 #include <string>
     18 #include <list>
     19 
     20 #define INPUT_FILE "in.txt"
     21 #define OUTPUT_FILE "out.txt"
     22 
     23 using namespace std;
     24 
     25 typedef long long LL;
     26 const int INF = INT_MAX / 2;
     27 
     28 void setfile() {
     29     freopen(INPUT_FILE,"r",stdin);
     30     freopen(OUTPUT_FILE,"w",stdout);
     31 }
     32 
     33 const int maxn = 13;
     34 
     35 int n,maxstate;
     36 LL w[maxn][maxn],c[maxn];
     37 LL note[maxn][maxn][1 << 13];
     38 LL cnt[maxn][maxn][1 << 13];
     39 
     40 LL dfs(int prev,int now,int state) {
     41     if(state == maxstate) return note[prev][now][state] = 0;
     42     LL ret = -1,nret; 
     43     if(note[prev][now][state] != -1) {
     44         return note[prev][now][state];
     45     }
     46     for(int i = 0;i < n;i++) {
     47         if((state & (1 << i)) == 0 && w[now][i] != -1) {
     48             LL addv = w[now][i] + c[i];
     49             if(w[prev][i] != -1) addv += c[i] * c[prev] * c[now];
     50             nret = dfs(now,i,state | (1 << i)) + addv;
     51             if(nret > ret) {
     52                 ret = nret;
     53             }
     54         }
     55     }
     56     if(ret == -1) return -INF * 100000LL;
     57     return note[prev][now][state] = ret;
     58 }
     59 
     60 LL getcount(int prev,int now,int state) {
     61     if(state == maxstate) return 1;
     62     if(cnt[prev][now][state] != -1) return cnt[prev][now][state];
     63     LL ret = 0;
     64     for(int i = 0;i < n;i++) {
     65         if((state & (1 << i)) == 0 && w[now][i] != -1) {
     66             LL addv = w[now][i] + c[i];
     67             if(w[prev][i] != -1) addv += c[i] * c[prev] * c[now];
     68             if(note[prev][now][state] == note[now][i][state | (1 << i)] + addv) {
     69                 ret += getcount(now,i,state | (1 << i));
     70             }
     71         }
     72     }
     73     return cnt[prev][now][state] = ret;
     74 }
     75 
     76 int main() {
     77     int T;
     78     cin >> T;
     79     while(T--) {
     80         memset(w,-1,sizeof(w));
     81         memset(cnt,-1,sizeof(cnt));
     82         memset(note,-1,sizeof(note));
     83         int m;
     84         cin >> n >> m;
     85         for(int i = 0;i < n;i++) {
     86             cin >> c[i];
     87         }
     88         for(int i = 0;i < m;i++) {
     89             int u,v;
     90             cin >> u >> v;
     91             u--; v--;
     92             w[u][v] = w[v][u] = c[u] * c[v];
     93         }
     94         maxstate = (1 << n) - 1;
     95         LL ans = 0,ccnt = 0;
     96         for(int i = 0;i < n;i++) {
     97             for(int j = 0;j < n;j++) if(i != j && w[i][j] != -1) {
     98                 LL ret = dfs(i,j,(1<<i)|(1<<j)) + w[i][j] + c[i] + c[j];
     99                 ans = max(ans,ret);
    100             }
    101         }
    102         for(int i = 0;i < n;i++) {    
    103             for(int j = 0;j < n;j++) {
    104                 if(note[i][j][(1 << i)|(1 << j)] + w[i][j] + c[i] + c[j] == ans) {
    105                     ccnt += getcount(i,j,(1<<j)|(1<<i));
    106                 }
    107             }
    108         }
    109         if(n == 1) cout << c[0] << " " << 1 << endl;
    110         else if(ccnt == 0) cout << "0 0" << endl;
    111         else cout << ans << " " << ccnt / 2 << endl;
    112     }
    113     return 0;
    114 }
  • 相关阅读:
    TensorFlow设置GPU占用量
    与服务器同步工程(expect脚本)
    C/C++中#pragma once的使用
    sublime text 3 快捷键大全
    Sublime Text 3 注册码
    如何用diff比较两个文件夹下的内容
    Error in building opencv with ffmpeg
    opencv: Rotate image by 90, 180 or 270 degrees
    初识HTTPS
    Unity3D之Mecanim动画系统学习笔记(十一):高级功能应用
  • 原文地址:https://www.cnblogs.com/rolight/p/3867620.html
Copyright © 2011-2022 走看看