zoukankan      html  css  js  c++  java
  • 状压dp-----三进制

    三进制的状压dp要先预处理3^n以及每一个数的每一位

    例题

    hdu3001

    题意:

    给定n 个城市已经 m 条路 以及对应路费 c,要求遍历所有城市最少的路费,每个城市不能超过2次。

    题解:

    看代码吧。。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    int n,m,minn;
    int load[12][12];
    int bit[12];
    int dp[60000][12];
    int num[60000][12];
    #define INF 1e8
    int main()
    {
      freopen("noip.in","r",stdin);
      freopen("noip.out","w",stdout);
          std::ios::sync_with_stdio(false);
          bit[0]=1;
          for (int i=1;i<=11;i++)
            bit[i]=bit[i-1]*3;
          for (int i=0;i<bit[10];i++)
          {
              int b=i;
              for (int j=0;j<10;j++)
              {
                num[i][j]=b%3;
                b/=3;
              }
          }
          while (cin>>n>>m)
          {
            memset(load,-1,sizeof(load));
            for (int i=0;i<m;i++)
            {
              int a,b,c;
              cin>>a>>b>>c;
              a--;b--;
              if (load[a][b]==-1)
                load[a][b]=load[b][a]=c;
              else 
                load[a][b]=load[b][a]=min(load[a][b],c);
            }
            memset(dp,-1,sizeof(dp));
            int flag,next;        for(int j = 0; j < n; j++)  
                dp[ bit[j] ][j] = 0;
            minn=INF;
            for(int i=0;i<bit[n];i++)
            {
              flag=1;
              for (int j=0;j<n;j++)
              {
                 if (num[i][j]==0) flag=0;
                 if (dp[i][j]==-1) continue;
                 for (int k=0;k<n;k++)
                 {
                   if (j==k||num[i][k]==2||load[k][j]==-1)
                     continue;
                   next=i+bit[k];
                   if (dp[next][k]==-1)
                     dp[next][k]=dp[i][j]+load[j][k];
                  else dp[next][k]=min(dp[next][k],dp[i][j]+load[j][k]); 
                 }
              }
              if (flag==1)
              {
                for (int j=0;j<n;j++)
                  if (dp[i][j]!=-1)
                    minn=min(minn,dp[i][j]);
              }
            }
          
                  if(minn == INF)  
                minn = -1;  
            printf("%d
    ", minn);
          }
          return 0;
    } 
  • 相关阅读:
    while循环
    三元运算符
    switch用法
    if判断
    位运算
    逻辑运算符
    赋值运算符和比较运算符
    算术运算符
    数据类型的转换
    线程同步之(条件变量)
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/8537287.html
Copyright © 2011-2022 走看看