zoukankan      html  css  js  c++  java
  • HDU 5691 Sitting in Line 状压dp

    dp[i][j][k]代表到第i个位置,第i个位置是j,k为已经选了i个数分别是那些(2进制状压)

    然后:其实真正有用的状态很少,可以写记忆化搜索,我写的BFS加速

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <stack>
    #include <vector>
    #include <map>
    #include <queue>
    #include <algorithm>
    #include <utility>
    using namespace std;
    typedef long long LL;
    const int N=15;
    const int INF=-15*(1e8+5);
    const LL mod=1e9+7;
    int dp[17][17][65537];
    bool inq[17][17][65537];
    int a[20],p[20],n;
    int vis[20];
    struct Node{
       int pos,u,cur;
       // Node(int a,int b,int c){pos=a;u=b;cur=c;}
    };
    queue<Node>q;
    int main()
    {
        int T,cas=0;
        scanf("%d",&T);
        while(T--){
           printf("Case #%d:
    ",++cas);
           memset(vis,0,sizeof(vis));
           scanf("%d",&n);
           for(int i=1;i<=n;++i){
            scanf("%d%d",&a[i],&p[i]);
            if(p[i]!=-1){
                ++p[i];
                vis[p[i]]=i;
            }
           }
           int l=(1<<n)-1;
           for(int i=0;i<=n;++i)
            for(int j=0;j<=n;++j)
             for(int k=0;k<=l;++k)
              dp[i][j][k]=INF;
            memset(inq,0,sizeof(inq));
            q.push(Node{0,0,0});dp[0][0][0]=0;
            while(!q.empty()){
               Node e=q.front();
               q.pop();
               int pos=e.pos+1;
               if(vis[pos]&&(e.cur&(1<<(vis[pos]-1)))==0){
                  int aim=e.cur|(1<<(vis[pos]-1));
                  if(dp[pos][vis[pos]][aim]==INF)q.push(Node{pos,vis[pos],aim});
                  dp[pos][vis[pos]][aim]=max(dp[pos][vis[pos]][aim],dp[e.pos][e.u][e.cur]+a[e.u]*a[vis[pos]]);
                  continue;
               }
               for(int i=1;i<=n;++i){
                  if(p[i]!=-1)continue;
                  if(e.cur&(1<<(i-1)))continue;
                  int aim=e.cur|(1<<(i-1));
                  if(dp[pos][i][aim]==INF)q.push(Node{pos,i,aim});
                  dp[pos][i][aim]=max(dp[pos][i][aim],dp[e.pos][e.u][e.cur]+a[e.u]*a[i]);
               }  
            }
            int ans=INF;
            for(int i=1;i<=n;++i)
             ans=max(ans,dp[n][i][l]);
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    上下界网络流——概念解析与快速入门(待修改)
    maomao的现在与未来
    exgcd证明和最基础应用
    快速入门Splay
    luogu 2515
    bzoj 1996
    *51nod 1409
    51nod 1412
    51nod 1503
    51nod 1020
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5521809.html
Copyright © 2011-2022 走看看