天天看点

Necklace(HDU-3091)Problem DescriptionInput OutputSample InputSample OutputSource Program

Problem Description

One day , Partychen gets several beads , he wants to make these beads a necklace . But not every beads can link to each other, every bead should link to some particular bead(s). Now , Partychen wants to know how many kinds of necklace he can make.

Input 

It consists of multi-case . 

Every case start with two integers N,M ( 1<=N<=18,M<=N*N ) 

The followed M lines contains two integers a,b ( 1<=a,b<=N ) which means the ath bead and the bth bead are able to be linked. 

Output

An integer , which means the number of kinds that the necklace could be.

Sample Input

3 3

1 2

1 3

2 3

Sample Output

2

题意:给出贝壳个数 n 以及 m 组贝壳能连接的关系,求最多可组成的项链数

思路:状压DP

n<=18,可以枚举所有情况,因此可将所有珠子压缩成一个二进制数,使用状压DP来做,用 dp[i][j] 表示到达状态 i 第 j 个珠子时的方案数

Source Program

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstdlib>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<ctime>
#include<vector>
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define N 20
#define MOD 10007
#define E 1e-6
#define LL long long
using namespace std;
int g[N][N];
LL dp[1<<N][N];
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF){
        memset(g,0,sizeof(g));
        memset(dp,0,sizeof(dp));

        while(m--){
            int x,y;
            scanf("%d%d",&x,&y);
            //存储连接关系
            g[x-1][y-1]=1;
            g[y-1][x-1]=1;
        }

        int allState=1<<n;
        dp[1][0]=1;
        for(int i=1;i<allState;i++)//枚举状态
            for(int j=0;j<n;j++)//枚举珠子个数
                if(dp[i][j]&&(i&(1<<j)))//判断条件
                    for(int k=1;k<n;k++)//枚举在当前珠子后面的珠子
                        if(!(i&(1<<k))&&g[j][k])
                            dp[i|(1<<k)][k]+=dp[i][j];


        LL res=0;
        for(int i=0;i<n;i++)
            if(g[0][i])
                res+=dp[allState-1][i];
        printf("%lld\n",res);
    }
    return 0;
}
           

继续阅读