zoukankan      html  css  js  c++  java
  • HDU

    Campus Design

     
    Nanjing University of Science and Technology is celebrating its 60th anniversary. In order to make room for student activities, to make the university a more pleasant place for learning, and to beautify the campus, the college administrator decided to start construction on an open space. 
    The designers measured the open space and come to a conclusion that the open space is a rectangle with a length of n meters and a width of m meters. Then they split the open space into n x m squares. To make it more beautiful, the designer decides to cover the open space with 1 x 1 bricks and 1 x 2 bricks, according to the following rules: 

    1. All the bricks can be placed horizontally or vertically 
    2. The vertexes of the bricks should be placed on integer lattice points 
    3. The number of 1 x 1 bricks shouldn’t be less than C or more than D. The number of 1 x 2 bricks is unlimited. 
    4. Some squares have a flowerbed on it, so it should not be covered by any brick. (We use 0 to represent a square with flowerbet and 1 to represent other squares) 

    Now the designers want to know how many ways are there to cover the open space, meeting the above requirements.

    InputThere are several test cases, please process till EOF. 
    Each test case starts with a line containing four integers N(1 <= N <= 100), M(1 <= M <= 10), C, D(1 <= C <= D <= 20). Then following N lines, each being a string with the length of M. The string consists of ‘0’ and ‘1’ only, where ‘0’ means the square should not be covered by any brick, and ‘1’ otherwise.OutputPlease print one line per test case. Each line should contain an integers representing the answer to the problem (mod 10 9 + 7).Sample Input

    1 1 0 0
    1
    1 1 1 2
    0
    1 1 1 2
    1
    1 2 1 2
    11
    1 2 0 2
    01
    1 2 0 2
    11
    2 2 0 0
    10
    10
    2 2 0 0
    01
    10
    2 2 0 0
    11
    11
    4 5 3 5
    11111
    11011
    10101
    11111

    Sample Output

    0
    0
    1
    1
    1
    2
    1
    0
    2
    954





    非常综合的一道轮廓线dp。开始给出已经存在的瓷砖位置,然后用1×1和1×2两种瓷砖铺满地面,其中1×1瓷砖又有限制。
    只需在状态中加一维表示1×1瓷砖个数,然后利用状压判断当前状态能否填满当前行即可。

    #include<bits/stdc++.h>
    #define MAX 102
    #define MOD 1000000007
    typedef long long ll;
    using namespace std;
    
    int n,m;
    char s[MAX][12];
    int a[MAX];
    ll dp[MAX][1<<10][22];
    struct Node{
        int pre,now,c;
    }node;
    vector<Node> v;
    
    void dfs(int pos,int pre,int now,int c){
        if(pos>m) return;
        if(pos==m){
            node.pre=pre;
            node.now=now;
            node.c=c;
            v.push_back(node);
            return;
        }
        dfs(pos+2,(pre<<2)|3,(now<<2)|3,c);      //横放1×2
        dfs(pos+1,pre<<1,(now<<1)|1,c);            //竖放1×2
        dfs(pos+1,(pre<<1)|1,now<<1,c);            //不放
        dfs(pos+1,(pre<<1)|1,(now<<1)|1,c+1);  //加入1×1
    }
    int main()
    {
        int t,i,j,k;
        int c,d;
        while(~scanf("%d%d%d%d",&n,&m,&c,&d)){
            v.clear();
            dfs(0,0,0,0);
            for(i=1;i<=n;i++){
                scanf(" %s",s[i]+1);
            }
            memset(dp,0,sizeof(dp));
            dp[0][(1<<m)-1][0]=1;
            for(i=1;i<=n;i++){
                for(j=0;j<v.size();j++){
                    int f=0;
                    for(k=1;k<=m;k++){
                        if(v[j].now&(1<<(m-k))){
                            if(s[i][k]=='0'){
                                f=1;
                                break;
                            }
                        }
                    }
                    if(f==1) continue;
                    int now=v[j].now;
                    for(k=1;k<=m;k++){
                        if(s[i][k]=='0'){
                            now|=1<<(m-k);
                        }
                    }
                    for(k=0;k<=20;k++){
                        if(k+v[j].c>20) break;
                        dp[i][now][k+v[j].c]+=dp[i-1][v[j].pre][k];
                        dp[i][now][k+v[j].c]%=MOD;
                    }
                }
            }
            ll ans=0;
            for(i=c;i<=d;i++){
                ans+=dp[n][(1<<m)-1][i];
                ans%=MOD;
            }
            printf("%I64d
    ",ans);
        }
        return 0;
        
    }
    
    
  • 相关阅读:
    Linux 基础 —— RPM
    mysql主从复制
    mysql.user表中Host为%的含义
    MySQL + Atlas --- 部署读写分离(参考02)
    MySQL读写分离技术(参考)
    蚁群算法
    java 回调
    java 接口sort comparable
    matlab 求解高阶方程
    matlab 求解常微分方程
  • 原文地址:https://www.cnblogs.com/yzm10/p/9687580.html
Copyright © 2011-2022 走看看