• bzoj2560串珠子


    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2560

    和地震后的幻想乡思路一样,枚举点集。

    因为求不连通容易,所以容斥一下,用全集减去不连通的。

    也还是为了不重不漏枚举一个划分点。

    哎呀真是一模一样呢!

    1.理解更深的一点:划分点的必要性。

      比如点集{1,2,3,4},如果不枚举划分点,减掉的东西里:1)当 f [ 1,2 ] 和 g [ 3,4 ] 的时候,含一个 f 1,2 ] x f [ 3,4 ],

                                 2)当 f [ 3,4 ] 和 g [ 1,2 ] 的时候,含一个 f [ 1,2 ] x f [ 3,4 ];

        所以必须枚举划分点。

    2.深刻的不明白的问题!

      发现如果指定连通的子集中必须包含划分点,就没问题;可是如果指定成连通的子集中必须不包含划分点,就错误。这是为什么?

        这都是因为那种  只有自己一个点还算联通  的情况太特殊了!

        考虑反例:其实就是会把那种图中一条边都没有的情况减好多遍。这种感觉。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define ll long long
    using namespace std;
    const int N=16;const ll mod=1e9+7;
    int n,c[N+5][N+5],lm;
    ll f[(1<<N)+5],g[(1<<N)+5];
    int main()
    {
        scanf("%d",&n);lm=(1<<n);
        for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%d",&c[i][j]);
        for(int s=1;s<lm;s++)
        {
            g[s]=1;
            for(int i=1;i<=n;i++)if(s&(1<<(i-1)))
                for(int j=i+1;j<=n;j++)if(s&(1<<(j-1)))
                    (g[s]*=c[i][j]+1)%=mod;
            f[s]=g[s];
            int k;
            for(k=1;k<=n&&(s&(1<<(k-1)))==0;k++);
    //        for(int j=((s-1)&s);j;j=((j-1)&s))if(j&(1<<(k-1)))    //50
    //            (f[s]-=f[j]*g[s^j])%=mod;
            k=(s^(1<<(k-1)));    //50
            for(int j=k;j;j=((j-1)&k))f[s]=((f[s]-g[j]*f[s^j])%mod+mod)%mod;//不是&s! 
    //        for(int j=((s-1)&s);j;j=((j-1)&s))if((j&(1<<(k-1)))==0)//49
    //            (f[s]-=f[j]*g[s^j])%=mod;
        }
        printf("%lld",f[lm-1]);
        return 0;
    }
  • 相关阅读:
    CSUOJ 1525 Algebraic Teamwork
    CSUOJ 1531 Jewelry Exhibition
    CSUOJ 1532 JuQueen
    POJ 2195 Going Home
    hiho week 37 P1 : 二分·二分查找之k小数
    POJ 2186 Popular Cows
    ZOJ 2532 Internship
    RQNOJ PID496/[IOI1999]花店橱窗布置
    POJ 3026 Borg Maze
    laravel框架总结(五) -- 服务提供者(提及契约Contracts)
  • 原文地址:https://www.cnblogs.com/Narh/p/9136604.html
Copyright © 2020-2023  润新知