Hdu 4804 Campus Design

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a1s4z5/article/details/53036300

有一个n×m(n100,m10)的棋盘,除了一些不能被覆盖的位置外其他的地方用1×21×1的骨牌填满,1×1的骨牌使用次数在[C,D]之间。问满足条件的方案数(mod109+7)


一个简单的插头dp入门题。

不能覆盖的地方可以视作必须放下1×1的骨牌并且不占使用的个数来简化代码。

因为直接列下状态数内存吃不消,用滚动数组优化即可


有的时候一些适当的注释能降低写代码的时候的脑力负担

#include<bits/stdc++.h>
using namespace std;

const int mod = 1e9+7;
char Map[112][12];
bool arr[112][12];
#define LL long long
int dp[2][1<<12][25];

inline int ge(int k,int j){return (k >> j) & 1;}
inline int sub(int k,int j){return k & (~(1<<j));}
inline int add(int k,int j){return k | (1<<j);}

int main(){
    int n,m,c,d;
    while(~scanf("%d %d %d %d",&n,&m,&c,&d)){
        memset(dp,0,sizeof(dp));
        for(int i = 1; i <= n;i++)
            scanf("%s",Map[i]);
        for(int i = 0;i <= n;i++){
            for(int j = 0;j < m;j++){
                arr[i][j] = (i>0) && (Map[i][j] == '1');
            }
        }
        int bnd = (1<<m) - 1;
        dp[0][bnd][0] = 1;
        for(int i = 1; i <= n;i++){
            for(int j = 0; j < m;j++){

                for(int k = 0 ; k <= bnd; k ++){
                    for(int lef = 0 ; lef <= d;lef++){
                        int &ndp = dp[1][k][lef];
                        if(arr[i][j]){ // can add
                            if(ge(k,j)){
                                (ndp += dp[0][sub(k,j)][lef] ) %= mod; // |
                                if(lef-1>=0) (ndp += dp[0][k][lef-1]) %= mod;  //. 
                                if(j && ge(k,j-1)) (ndp += dp[0][sub(k,j-1)][lef]) %= mod; //- 
                            }
                            else (ndp += dp[0][add(k,j)][lef])%=mod;    //empty
                        }
                        else if(ge(k,j)) (ndp += dp[0][k][lef])%=mod; //only have .
                    }
                }

                for(int k = 0 ; k <= bnd; k ++){
                    for(int lef = 0 ; lef <= d;lef++){
                        dp[0][k][lef] = dp[1][k][lef];
                        dp[1][k][lef] = 0;
                    }
                }
            }
        }
        int ans = 0;
        for(int lef = c ; lef <= d;lef++){
            (ans += dp[0][bnd][lef] ) %= mod;
        }
        printf("%d\n",ans);
    }
    return 0;
}
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页