zoukankan      html  css  js  c++  java
  • [BZOJ 2734] 集合选数

    Link:

    BZOJ 2734 传送门

    Solution:

    真是奥妙重重的建模啊.....

    我们发现$x,2*x,3*x$这些数太分散了,难以处理

    于是我们构建这样的表格:

    x  3x  9x  27x....

    2x  6x  18x  54x...

    4x  12x   36x  108x...

    ...   .....    .....    ......

    将问题转化为求表格上任意两点不相邻的点集数

    由于$2^{17}>100000$,因此直接对每一行的信息状压就行了

    设$dp[i][j]$为到第$i$行且其状态为$j$时的方案总数,上一层状态为$k$,判断!(k&j) && !(j&(j>>1))即可

    Note:由于一个表格不能包含所有数,因此要建多个表格,结果相乘

    Code:

    //by NewErA
    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    const int MOD=1e9+1;
    
    const int MAXN=100005;
    ll n,dp[50][MAXN],dat[50][50],len[50],last;
    bool vis[MAXN];
    
    ll cal(int x)
    {
        dat[1][1]=x;
        for(int i=1;;i++)
        {
            if(i>1) dat[i][1]=dat[i-1][1]*2;
            if(dat[i][1]>n){last=i-1;break;}
            vis[dat[i][1]]=true;
            
            for(int j=2;;j++)
            {
                dat[i][j]=dat[i][j-1]*3;
                if(dat[i][j]>n){len[i]=j-1;break;}
                vis[dat[i][j]]=true;
            }
        }
        
        for(int i=0;i<=last+1;i++)
            for(int j=0;j<=(1<<len[i]);j++) dp[i][j]=0;
        
        dp[0][0]=1;len[0]=1; //状压DP
        for(int i=0;i<=last;i++)
            for(int j=0;j<(1<<len[i]);j++)
                if(dp[i][j])
                    for(int k=0;k<(1<<len[i+1]);k++)
                        if(!(j&k) && !(k&(k>>1))) dp[i+1][k]=(dp[i+1][k]+dp[i][j])%MOD;
        return dp[last+1][0];
    }
    
    int main()
    {
        cin >> n;
        ll res=1;
        for(int i=1;i<=n;i++)
            if(!vis[i]) res=res*cal(i)%MOD;
        cout << res;
        return 0;
    }

    Review:

    1、当信息较为分散时,通过构建矩阵等各类方式将相关条件集中处理

    2、求矩阵中任意两点不相邻的点集数(经典问题)

    状压DP的应用,整体$!(j&k)$和$!k&(k>>1)$判断的方式还行

  • 相关阅读:
    在linux上安装python, jupyter, 虚拟环境(virtualenv)以及 虚拟环境管理之virtualenvwraper
    linux
    Django ORM那些相关操作
    Django 中 form 介绍
    MySQL完整性约束
    git入门
    MySQL表的操作
    努力努力再努力
    Docker初始
    IO模型
  • 原文地址:https://www.cnblogs.com/newera/p/9141390.html
Copyright © 2011-2022 走看看