zoukankan      html  css  js  c++  java
  • 5.9总结

    打开题面:

    看到t3的题目,点进去看了看,很好,再见,点进去t1看了看,是个状压,想了一下,应该是三进制,想优化,不会,于是想dfs,看能不能剪枝,先走了,看了看t2,嗯,是个dp,突然发现今天三道都是概率,瑟瑟发抖,于是不想写,……,于是被迫写,看了看t3,gauss一波应该也行,于是回去看最有可能做出来的t2,话说t2我见过,但是没写,就是因为记得不是在写概率的时候见的,所以才敢看,想了一个dp,想着把vi固定,求出di,想了个o(n)的dp,感觉还行,开始写,写完开始调,调到11点过了样例,一交全WA,不慌,又是磕几个样例,没发现有问题啊???又试了long long 也没问题,不会是我dp想错了把,感觉没问题啊??? 但是11点多了,赶紧去写t1,dfs写完了,一稿样例,过了,但是突然反应过来,这样做没有消除非独立集点的影响,12点多了,好慌啊,赶紧打了个10分的暴力,连10分的暴力都打的磕磕巴巴,写了2、30分钟,踩着点交的。

    总结:

    看到题了不要慌,慌了也不要不写,就算难也不是拿不到分,至少要把最暴力的拿了。

    看到像什么算法,也不要局限在类似算法上,想想类似的其他题我是怎么做的,也不要想非常nb的算法,像非常简单的算法差分啊,模拟啊,都有可能拿到分,可能会有不一样的收获

    现在又要加上一条了,一定要看清树的形态,二叉、多叉、链

    题解:

    搞事的时候没有想到也正常,从来主动没有这样想过或者运用过这种扩展的思想

    https://www.luogu.com.cn/blog/user29936/solution-p5492

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=22,p=998244353;
    typedef long long ll;
    int siz[(1<<20)+5],n,g[N][N],f[(1<<20)+5],ones[(1<<20)+5],one[(1<<20)+5];
    //siz 是集合  s[i]=ones[siz[i]];
    vector<int> S[N];
    int get(int s)
    {
        int cnt=0;
        while(s) cnt++,s-=s&-s;
        return cnt;
    }
    int inv[N];
    void init()
    {
        inv[0]=inv[1]=1;
        for(int i=2;i<=n;i++) inv[i]=-1ll*p/i*inv[p%i]%p;
    }
    bool b[(1<<20)+5],is[(1<<20)+5];
    int main()
    {
        freopen("algorithm.in","r",stdin);
        freopen("algorithm.out","w",stdout);
        int m;
        cin>>n>>m;
        init();
        int x,y;
        while(m--)
        {
            cin>>x>>y;
            g[x][y]=g[y][x]=1;
        }
        
        for(int i=0;i<(1<<n);i++) ones[i]=get(i),S[ones[i]].push_back(i);
        for(int i=0;i<n;i++) one[1<<i]=i+1;
        //每次只扩展一个点
        siz[0]=0;
        is[0]=1;
        //判断独立集
        for(int s=1;s<(1<<n);s++)
        {
            int t=s&-s;
            if(!is[s^t]) continue;
            siz[s]=siz[s^t];
            is[s]=1;
            int k=t;
            t=one[t];
            for(int j=1;j<=n;j++)
            if(t^j&&s>>(j-1)&1&&g[t][j]) is[s]=0;
            if(!is[s]) continue;
            for(int j=1;j<=n;j++)
            if(g[j][t]) k|=(1<<(j-1));
            siz[s]|=k;
        }
        
        f[0]=1;
        b[0]=1;
        for(int s=1;s<(1<<n);s++)
        {
            if(!is[s]) continue;
            for(int i=1;i<=n;i++)
            if(s>>(i-1)&1) f[s]=(f[s]+1ll*f[s^(1<<(i-1))]*inv[n-ones[siz[s^(1<<(i-1))]]]%p)%p,b[s]|=b[s^(1<<(i-1))];
        }
        for(int i=n;i>=1;i--)
        {
            int ans=0,fl=0;
            for(int j=0;j<S[i].size();j++)
            {
                ans=(ans+f[S[i][j]])%p;
                fl|=b[S[i][j]];
            }
            if(fl) {
                cout<<(ans+p)%p;
                break;
            }
        }
        
        return 0;
    }

    t2:

    话说也不知道为什么40分不对??

    但是正解的dp和我的不一样

    40分:

    把叶子的val排序,变成v1,v2,v3……

    f[x][i] 在x位置处出现v[i]的概率,l是左孩子,r是右孩子

    f[x][i] = px * ( f[l][i ]* Σ f[r][k] + f[r][i] * Σ f[l][k] ) (k=1,2,……i-1) + (1-px) * (f[l][i ]* Σ f[r][k] + f[r][i] * Σ f[l][k]) (k=i+1,i+2,……cnt_v)

    前缀和优化一下就行了

     正解套一个线段树合并

  • 相关阅读:
    【41】了解隐式接口和编译期多态
    【17】以独立语句将newed对象置入智能指针
    【16】成对使用new和delete时要采取相同形式
    【15】在资源管理类中提供对原始资源的访问
    【14】在资源管理类中小心copying行为
    【02】尽量以const,enum,inline替换#define
    【01】视C++为一个语言联邦
    一次数据库hang住的分析过程
    针对某个数据库error做systemstate dump
    数据库hang住如何收集信息
  • 原文地址:https://www.cnblogs.com/xsm098/p/14748132.html
Copyright © 2011-2022 走看看