zoukankan      html  css  js  c++  java
  • HDU 3091 Necklace <<状压dp

    题意

    要把一些珠子串成一串,每个珠子只可以和限制特定的别的珠子串在一起,给定珠子数量和限制条件,求能组成的不同的项链的种数。

    思路

    看数据范围,再加上这是有限制条件的问题求解,很容易发现是状压dp的问题。dp[i][j]表示放下第i个珠子后的状态为j(即i为前一个珠子),只要保证下一个珠子能和前一个接的上就可行。那么枚举k为下一个珠子,看是否可行即可,具体看代码。然后细节上,点的下标与dp中的状态要统一起来才不会出错。

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 long long dp[20][1<<18];
     4 int G[20][20];//数据范围小,只需要判断是否邻接,所以矩阵很方便
     5 int main()
     6 {
     7     int n,m;
     8     while(~scanf("%d%d",&n,&m))
     9     {
    10         memset(dp,0,sizeof(dp));
    11         memset(G,0,sizeof(G));
    12         for(int i=0,a,b;i<m;i++)
    13         {
    14             scanf("%d%d",&a,&b);
    15             G[a][b]=G[b][a]=1;//这里没统一下标,所以后面写的时候出现了很多麻烦
    16         }
    17         dp[0][1]=1;//因为是个环,所以任意选取一颗珠子作为开头,此处选1
    18         for(int i=1;i<(1<<n);i++)
    19         {
    20             for(int j=0;j<n;j++)
    21             {
    22                 if(dp[j][i]==0) continue;//如果此状态不可达,跳过
    23                 for(int k=0;k<n;k++)
    24                 {
    25                     if(i&(1<<k)) continue;//如果这个珠子已经放了,跳过
    26                     if(G[k+1][j+1]) dp[k][i|(1<<k)]+=dp[j][i];//如果k与j(前一个珠子)能接上,就可以状态转移
    27                 }
    28             }
    29         }
    30         long long ans=0;
    31         for(int i=0;i<=n;i++)
    32         {
    33             if(G[1][i+1])//看最后一颗珠子与第一颗是否连的起来
    34                 ans+=dp[i][(1<<n)-1];
    35         }
    36         printf("%lld
    ",ans);
    37     }
    38 }

    后记

    这题一开始用了三维dp,多了一维表示第一个珠子,然后最后再除阶乘得出答案,然而事实上由于是个环,所以从哪个珠子开始关系并不大。从这题上还是学到了很多的。

  • 相关阅读:
    LeetCode "Palindrome Partition II"
    LeetCode "Longest Substring Without Repeating Characters"
    LeetCode "Wildcard Matching"
    LeetCode "Best Time to Buy and Sell Stock II"
    LeetCodeEPI "Best Time to Buy and Sell Stock"
    LeetCode "Substring with Concatenation of All Words"
    LeetCode "Word Break II"
    LeetCode "Word Break"
    Some thoughts..
    LeetCode "Longest Valid Parentheses"
  • 原文地址:https://www.cnblogs.com/computer-luo/p/10061659.html
Copyright © 2011-2022 走看看