zoukankan      html  css  js  c++  java
  • O

    题目链接

    题目大意

    给你一个方形矩阵mp,边长为n(n<=21)

    有n个男生和女生,如果(mp[i][j]=1) 代表第i个男生可以和第j个女生配对

    问有多少种两两配对的方式,使得所有男生和女生都一一匹配

    题目思路

    看数据显然是一个状压dp

    (dp[i][j])表示前i个男生匹配的女生的状态为j,三重for即可

    优化:但是枚举状态的时候其实判断有多少个1就已经知道有多少个人被匹配了,那么其实枚举人数是没有必要的,可以先枚举状态然后判断人数即可优化一维循环,当然数组也可以滚动优化代码懒得写了

    代码

    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<cstdio>
    #include<vector>
    #include<string>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<unordered_map>
    #define fi first
    #define se second
    #define debug printf(" I am here
    ");
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> pii;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    const int maxn=20+5,inf=0x3f3f3f3f,mod=1e9+7;
    const double eps=1e-10;
    int n;
    int mp[maxn][maxn];
    ll dp[maxn][1<<21];
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                scanf("%d",&mp[i][j]);
            }
        }
        dp[0][0]=1;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                int now=1<<(j-1);
                if(!mp[i][j]) continue;
                for(int pre=0;pre<=(1<<n)-1;pre++){
                    if(dp[i-1][pre]&&(now&pre)==0){
                        dp[i][pre|now]+=dp[i-1][pre];
                        dp[i][pre|now]%=mod;
                    }
                }
            }
        }
        printf("%lld
    ",dp[n][(1<<n)-1]);
        return 0;
    }
    
    
  • 相关阅读:
    梦心日记本V2.0终于要完工了
    上班半年大总结
    真有趣
    搞定设计模式1之策略模式
    利用GDI+制作背景颜色淡入淡出效果的按钮
    浏览器之争
    学习自定义控件
    搞定设计模式2之代理模式
    (转)学习asp.net比较完整的流程
    搞定设计模式3之中介者模式
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/14019989.html
Copyright © 2011-2022 走看看