zoukankan      html  css  js  c++  java
  • bzoj2734:[HNOI2012]集合选数(状压DP)

      菜菜的喵喵题~

      化序列为矩阵!化腐朽为神奇!左上角为1,往右每次*3,往下每次*2,这样子就把问题转化成了在矩阵里选不相邻的数有几种可能。

      举个矩阵的例子

      1 3 9 27
      2 6 18 54
      4 12 36 108

      这样最多11列,最多17行,那么方案数就可以用状压了。 

      但是我们会发现,矩阵里没有5,所以我们要把5作为左上角再算一次答案,最后把所有矩阵的答案用乘法原理乘起来就好

    #include<iostream> 
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath> 
    #include<algorithm> 
    #define MOD(x) ((x)>=mod?(x)-mod:(x))
    using namespace std;
    const int maxn=500010,mod=1e9+1;
    int n,ans,cnth;
    int f[20][1<<11],cntl[20];
    bool v[maxn];
    inline void read(int &k)
    {
        int f=1;k=0;char c=getchar();
        while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
        while(c<='9'&&c>='0')k=k*10+c-'0',c=getchar();
        k*=f;
    }
    inline int find(int x)
    {
        cnth=0;memset(cntl,0,sizeof(cntl));
        for(int i=1,fir=x;fir<=n;i++,fir*=2,cnth++)
        for(int j=1,sec=fir;sec<=n;j++,sec*=3,cntl[i]++)v[sec]=1;
        f[0][0]=1;
        for(int i=1;i<=cnth;i++)for(int j=0;j<=(1<<cntl[1])-1;j++)f[i][j]=0;
        for(int i=1;i<=cnth;i++)
        for(int j=0;j<(1<<cntl[i]);j++)
        if(!(j&(j>>1)))
        for(int k=0;k<(1<<cntl[i-1]);k++)
        if(!(k&(k>>1)))if(!(j&k))f[i][j]=MOD(f[i][j]+f[i-1][k]);
        int sum=0;
        for(int i=0;i<=(1<<cntl[cnth])-1;i++)sum=MOD(sum+f[cnth][i]);
        return sum;
    }
    int main()
    {
        read(n);ans=1;
        for(int i=1;i<=n;i++)
        if(!v[i])ans=1ll*ans*find(i)%mod;
        printf("%d
    ",ans);
    }
    View Code
  • 相关阅读:
    高级搜索
    Hibernate通过什么方法可以把私有成员变量赋值成数据库查询到的值然后返回POJO对象呢?
    hibernate继承关系映射和java反射机制的运用
    eclipse启动停止--jdk环境变量配置
    visual studio 正则表达式 查找 替换
    常用正则表达式
    解决兼容的方法!
    JS的定时器和JS的执行机制
    2020年3月2日随笔
    2020年2月12日 线上笔记
  • 原文地址:https://www.cnblogs.com/Sakits/p/7693341.html
Copyright © 2011-2022 走看看