zoukankan      html  css  js  c++  java
  • 「PKUWC2019」拓扑序计数(状压dp)

    考场只打了 (52) 分暴力。。。(ljc) 跟我说了一下大致思路,我回去敲了敲。

    (f[i]) 表示状态为 (i) 时的方案数。我们用二进制 (0/1) 表示不选/选点 (i)

    我们设 (jin i) 且拓扑序最小。

    [f[i]=sum f[i ext{^}2^j] imes 2^{i&w[j]} ]

    为什么这个是对的呢?

    因为 (j) 连出的那些没有连向状态 (i) 的边一定会被删去,然后那些连向边只用 (2^i) 搞一搞。时间复杂度 (O(n2^n))

    刚手玩了几组数据好像没错,先放上来好了。

    (Code Below:)

    #include <bits/stdc++.h>
    using namespace std;
    const int mod=998244353;
    int n,m,lim,bin[30],w[30],f[1<<20],cnt[1<<20];
    
    int main()
    {
    	scanf("%d%d",&n,&m);lim=(1<<n)-1;
    	int x,y;
    	for(int i=0;i<m;i++){
    		scanf("%d%d",&x,&y);
    		x--;y--;w[x]|=1<<y;
    	}
    	bin[0]=1;
    	for(int i=1;i<=n;i++) bin[i]=bin[i-1]<<1;
    	for(int i=1;i<=lim;i++) cnt[i]=cnt[i>>1]+(i&1);
    	f[0]=1;
    	for(int i=1;i<=lim;i++)
    		for(int j=0;j<n;j++)
    			if(i&bin[j]) f[i]=(f[i]+1ll*f[i^bin[j]]*bin[cnt[i&w[j]]]%mod)%mod;
    	printf("%d
    ",f[lim]);
    	return 0;
    }
    
  • 相关阅读:
    Codeforces Round #411 (Div. 2)
    腾讯比赛资料
    AtCoder Beginner Contest 060
    hdu 5288 数学 ****
    hdu 1866 几个矩形面积的和 ***
    hdu 2232 矩阵 ***
    bzoj 1415 期望+记忆化搜索 ****
    hdu 5033 单调栈 ****
    hdu 3032 sg打表找规律 *
    hdu 2516 FIB博弈
  • 原文地址:https://www.cnblogs.com/owencodeisking/p/10300562.html
Copyright © 2011-2022 走看看