zoukankan      html  css  js  c++  java
  • poj 2411 Mondriaan's Dream 状态压缩dp

     邓姐推荐做这道题,果然是一道不错的题目,据说是插头dp,不过我不会哦,咋办呢,这种题只好暴力乱搞了

    一开始用3进制来存储状态 0代表横放 1代表竖着放朝上 2代表竖着放朝下 然后暴力搜了一下 复杂度3^22 果断超时了

    后来想了一下,其实上一行的每个格子状态都搜完了之后,只要不是朝下 那么就对下一行没有影响了 于是更改了一下状态存储方式

    0代表这个格子放的方式不会影响下一行 1代表会影响下一行

    容易证明 不冲突的两行 下一行有且只有一种合法的方式

    所以复杂度就从 3^22缩减到了2^22  并且二进制存储与位运算 速度飞快 就过了

    具体的就看代码咯

    View Code
    Source Code
    
    Problem: 2411        User: tangrui
    Memory: 416K        Time: 47MS
    Language: C++        Result: Accepted
    Source Code
    #include<iostream>
    #include<cmath>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int n,m;
    long long t[(1<<11)+10][11];
    int x;
    // 0代表仅占自己这行 1代表竖着放占了下一行
    int selfcheck(int a)
    {
        int odd=0;         //相邻的两行同样位置都是0代表这个位置是横着放的 因此必须是偶数个
        for(int k=a,i=0;i<n;i++)
        {
            if(!(k&1))odd=!odd;
            else if(odd) return 0;
            k>>=1;
        }
        if(odd) return 0;
        return 1;
    }
    int correct(int a,int b)
    {
        if(a&b)return 0;          //当相邻的两行有同样位置的两个1时一定是冲突的
        return selfcheck(a|b);  
    }
    long long dp(int now,int k)
    {
    
        if(k==m-1)
        {
            return correct(0,now); //因为最后一行状态只能是0 所以倒数第二行就判断
        }   
        if(t[now][k])return t[now][k]; //你懂的
        for(int i=0;i<x;i++)
        {
            if(correct(i, now))
                t[now][k]+=dp(i,k+1);
        }
        return t[now][k];
    }
    int main()
    {
        while(cin>>n>>m&&(n|m))
        {
            if(n==0||m==0||n*m%2==1)
            {
                cout<<0<<endl;
                continue;
            }
            memset(t,0,sizeof(t));
            if(n>m) swap(n,m);  //为了时间 尽量让n小些
             x=1<<n;            //每一行的总状态数为 2^n
            cout<<dp(0,0)<<endl;
        }
    }
  • 相关阅读:
    ar游戏开发入门三步走
    什么是 OpenCL OpenGL
    https 服务器搭建
    javascript 访问cookie信息
    手机网页制作需要注意的一点东西
    asp.net下载文件几种方式
    javascriptM
    PDF转JPG
    java实现PDF转HTML
    关于mysql ERROR 1045 (28000)错误的解决办法
  • 原文地址:https://www.cnblogs.com/goagain/p/2802772.html
Copyright © 2011-2022 走看看