zoukankan      html  css  js  c++  java
  • hdu 5691(状压DP) Sitting in Line

    题目http://acm.hdu.edu.cn/showproblem.php?pid=5691

    状态DP,dp[i][j],i 表示的是一种状态,这个状态指的是当前这个数取或不取,j表示的是以第j个数结尾,

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 typedef long long ll;
     8 ll dp[1<<17][20];
     9 
    10 int num[20],dis[20],vis[20];
    11 ll max(ll x,ll y) {return x>y?x:y;}
    12 const ll INF=1e18;
    13 
    14 int main()
    15 {
    16     int t,n,pos=0;
    17     scanf("%d",&t);
    18     while (t--)
    19     {
    20         scanf("%d",&n);
    21         memset(vis,-1,sizeof(vis));
    22         for(int i=0;i<(1<<n);i++)
    23             for(int j=0;j<n;j++)
    24                 dp[i][j] = -INF;
    25         for (int i=0 ; i<n ; i++) {
    26             scanf("%d%d",&num[i],&dis[i]);
    27             if (dis[i]!=-1)
    28                 vis[dis[i]]=i;
    29         }
    30         if (vis[0]!=-1) dp[(1<<vis[0])][vis[0]]=0;// 0这个位子被占用了
    31         else{
    32             for (int i=0 ; i<n ; i++) // 没有特定位置
    33                 if (dis[i]==-1) dp[(1<<i)][i]=0; //
    34         }
    35         int cas=(1<<n)-1;
    36         for (int i=1 ; i<=cas ; i++){
    37             int ans=0;
    38             for (int j=0 ; j<n ; j++)
    39                 if (i&(1<<j))
    40                    ans++;
    41             if (vis[ans]!=-1)
    42             {
    43                 ans=vis[ans];
    44                 for (int j=0 ; j<n ; j++)
    45                     if ((i&(1<<j))&&j!=ans)
    46                         dp[i|(1<<ans)][ans]=max(dp[i|(1<<ans)][ans],dp[i][j]+num[j]*num[ans]);
    47             }
    48             else
    49             {
    50                for (int j=0 ; j<n ; j++){
    51                    if (i&(1<<j)){
    52                       for (int k=0 ; k<n ; k++){
    53                           if (!(i&(1<<k))){
    54                               dp[i|(1<<k)][k]=max(dp[i|(1<<k)][k],dp[i][j]+num[k]*num[j]);
    55                           }
    56                       }
    57                    }
    58                }
    59             }
    60         }
    61         printf("Case #%d:
    ",++pos);
    62         ll maxn=-INF;
    63         for (int i=0 ; i<n ; i++)
    64             maxn=max(maxn,dp[cas][i]);
    65         printf("%I64d
    ",maxn);
    66     }
    67     return 0;
    68 }
    View Code
  • 相关阅读:
    HDU6030 Happy Necklace(推导+矩阵快速幂)
    威尔逊定理总结
    卢卡斯定理总结
    扩展欧几里得总结
    HDU2602 Bone Collector(01背包)
    离散数学--集合论
    Linux超全实用指令大全
    HDU6715 算术(莫比乌斯反演)
    莫比乌斯反演总结
    k8s-基于kubeasz项目二进制部署k8s集群
  • 原文地址:https://www.cnblogs.com/JJCHEHEDA/p/5666955.html
Copyright © 2011-2022 走看看