• 【cqbzoj】1785:残缺棋盘上放车的方案数 --状压dp --输入毁一生


    【高级算法】残缺棋盘上放车的方案数

      时间限制: 1 Sec  内存限制: 64 MB

    题目描述

      在 n*n(n≤20)的方格棋盘上放置 n 个车,某些格子不能放,求使它们不能互相攻击的方案总数。

    我们将每一行允许放棋子的位置设为1,禁止的位置设为0,例如1101表示该行上的第2列禁止放棋子。

    输入

    第1行:1个整数n

    接下来n行,每行n个0、1数字,表示第i行的允许禁止状态

    输出

    第1行:1个整数,表示放置方案的总数

    样例输入

    5
    00111
    01110
    00110
    01011
    10011
    

    样例输出

    5


    思路:就是状压DP

    状态表示目前到第i行已经在那几列放了棋子时摆放的方案数

    DP时考录当行限制增加棋子累加即可(应该没问题吧?应该是的。。。)

    实现使用两个数组互相交换指针

    注意由于n=20,答案可能超出int范围,所以用long long开数组



    事实上我还没有过掉这道题。。

    写了暴力dfs对拍了19000+组数据还是没异常。。

    等把错误弄清了再修改

    希望有看出错误的大神指出错误!大笑



    把这道题过了。。

    原来是getchar的问题。。

    再也不用getchar了。。。。

    #include<cstdio>
    #include<cstring>
    #define ULL unsigned long long
    #define MAXS (1<<20)
    #define LL long long
    ULL f1[MAXS],f2[MAXS];
    int level[22];
    char str[30];
    int lowbit(int a)
    {return a&-a;}
    int main(){
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){//= =  就是这里。。
            scanf("%s",str);
            for(int j=0;j<n;j++)
                level[i]<<=1,
                level[i]+=str[j]-'0';
        }
    	
        ULL *p1=f1,*p2=f2,*tmp;
        int t1=level[1],t2,nn=(1<<n)-1;
        while(t1){
            t2=lowbit(t1);
            t1-=t2;
            p1[(~t2)&nn]=1;
        }
    	
        for(int i=1;i<n;i++){
            memset(p2,0,sizeof f1);//sizeof f1==sizeof f2
            for(int j=1;j<=nn;j++)
                if(p1[j])for(int k=j,q=lowbit(j);k;k-=q,q=lowbit(k))
                        if((level[i+1]|q)==level[i+1])
                            p2[(~q)&j]+=p1[j];
            tmp=p1;
            p1=p2;
            p2=tmp;
        }
        printf("%llu",p1[0]);
    }
    


  • 相关阅读:
    实体类实现序列化
    异常处理
    Springboot的模块化使用
    Springboot的开始
    RxJava用法
    okhttp的Post方式
    OKhttp使用
    soundPool声音池
    ScheduledExecutor定时器
    timer定时器
  • 原文地址:https://www.cnblogs.com/Hineven/p/5843576.html
Copyright © 2020-2023  润新知