HDU3091 (2n个分成n对使得结果最小 n小于等于10 状压dp 根据题目特性减少状态)

题目
在这里插入图片描述
转自
在这里插入图片描述

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=19;
int ok[N][N],A[N],B[N];ll dp[1<<N][N];
int main(){
    int n,m;
    while(~scanf("%d%d",&n,&m)){
        memset(ok,0,sizeof ok),memset(dp,0,sizeof dp);dp[1][1]=1;
        for(int i=1,x,y;i<=m;++i) scanf("%d%d",&x,&y),ok[x][y]=ok[y][x]=1;
        int t=1<<n;
        for(int i=0;i<t;++i){
            int o1=0,o2=0;
            for(int j=1;j<=n;++j) (i&(1<<(j-1)))?(A[++o1]=j):B[++o2]=j;
            for(int x=1;x<=o1;++x)
                for(int y=1;y<=o2;++y) if(ok[A[x]][B[y]]) dp[i|(1<<(B[y]-1))][B[y]]+=dp[i][A[x]];
        }
        ll ans=0;
        for(int i=1;i<=n;++i) if(ok[1][i]) ans+=dp[t-1][i];
        printf("%lld\n",ans);
    }
}
©️2020 CSDN 皮肤主题: 终极编程指南 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值