状态压缩动态规划——布阵类问题

这三道题目异曲同工,如果不能完成,那么看懂一道题的题解后,自己实现剩余两道应该没有问题

顺便附一个状压dp的视频讲解
点此进入
POJ-3254 Corn Fields

#include<cstdio>
#include<algorithm>
#include<cstring>

const int MOD=100000000,STATE=1<<12,ROW=12+1;

int St[STATE+1],Bare[ROW],dp[ROW][STATE];

int main(){
    int k=0;
    for(int i=0;i<STATE;++i)if(!(i&(i<<1)))St[k++]=i;//每行所有的合法状态
    St[k]=STATE;
    int m,n,t;
    scanf("%d%d",&m,&n);
    for(int i=0;i<m;++i){
        for(int j=0;j<n;++j){
            scanf("%d",&t);Bare[i]=(Bare[i]<<1)|(!t);
        }
    }
    int s=1<<n;
    for(int i=0;St[i]<s;++i)if(!(Bare[0]&St[i]))dp[0][i]=1;
    for(int r=1;r<m;++r){
        for(int i=0;St[i]<s;++i){
            if(!(Bare[r-1]&St[i])){
                for(int ri=0;St[ri]<s;++ri){
                    if(!(Bare[r]&St[ri]) && !(St[i]&St[ri])){
                        dp[r][ri]=(dp[r][ri]+dp[r-1][i])%MOD;
                    }
                }
            }
        }
    }
    int ans=dp[m-1][0];
    for(int i=1;St[i]<s;++i){
        ans=(ans+dp[m-1][i])%MOD;
    }
    printf("%d\n",ans);
    return 0;
}

HDU-4539 排兵布阵

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>

const int STATE=1<<10;
int dp[101][180][180],num[1<<10+1],St[201],marsh[201];

int get_bit1(int x){
    int nx=0;
    while(x){
        if(x%2)nx++;
        x/=2;
    }
    return nx;
}

bool ok(int x,int y){
    if(x & y<<1 || x<<1 & y) return 0; 
    return 1;
}

int main(){
    int m,n,k=0;
    for(int i=0;i<STATE;++i){
        if(!(i&(i<<2)))St[k++]=i;
        num[i]=get_bit1(i);
    }
    St[k]=STATE;
    //std::cout<<k<<"\n";
    while(scanf("%d%d",&n,&m)==2&&n){
        memset(dp,-1,sizeof(dp));
        int t;
        for(int i=0;i<n;++i){
            marsh[i]=0;
            for(int j=0;j<m;++j){
                scanf("%d",&t);marsh[i]=(marsh[i]<<1)|(!t);
            }
        }
        int s=1<<m;
        for(int i=0;St[i]<s;++i){
            if(!(marsh[0]&St[i]))
            for(int j=0;St[j]<s;++j){
                dp[0][i][j]=num[St[i]];
            }
        }

        for(int i=0;St[i]<s;++i){
            if(!(marsh[1]&St[i]))
            for(int j=0;St[j]<s;++j){
                if(ok(St[i],St[j]) && !(marsh[0]&St[j]))
                for(int kk=0;St[kk]<s;++kk){
                    if(dp[0][j][kk]!=-1)dp[1][i][j]=std::max(dp[0][j][kk]+num[St[i]],dp[1][i][j]); 
                }

            }
        }

        for(int r=2;r<n;++r){
            for(int i=0;St[i]<s;++i){
                if(!(St[i]&marsh[r-2])){
                    for(int ri1=0;St[ri1]<s;++ri1){
                        if(!(St[ri1]&marsh[r-1])){
                            for(int ri=0;St[ri]<s;++ri){
                                if(!(St[ri]&marsh[r]) && (!(St[i]&St[ri])) && ok(St[ri1],St[ri]) ){
                                    if(dp[r-1][ri1][i]!=-1)
                                    dp[r][ri][ri1]=std::max(dp[r][ri][ri1],dp[r-1][ri1][i]+num[St[ri]]);
                                }
                            }
                        }
                    }
                }
            }
        }
        int ans=0;
        for(int i=0;St[i]<s;++i)
        {
            for(int j=0;St[j]<s;++j)
            ans = std::max(ans,dp[n-1][i][j]);
        }
        printf("%d\n",ans);
    }
    return 0;
}

POJ-1185 炮兵布阵

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
const int STATE=1<<11,ROW=101;

inline int get_bit1(int x){
    int nx=0;
    while(x){
        if(x%2)nx++;
        x/=2;
    }
    return nx;
}

int st[101],n,m,marsh[101],dp[ROW][101][101],ST,num[STATE];
char tab[ROW][10+1];

inline void init(){
    for(int i=0;i<n;++i){
        marsh[i]=0;
        for(int j=0;j<m;++j)
            if(tab[i][j]!='P')marsh[i]=(marsh[i]<<1)|1;
            else marsh[i]=marsh[i]<<1;
    }
    memset(dp,-1,sizeof(dp));
    ST=1<<m;
    for(int i=0;st[i]<ST;++i){
        if(!(marsh[0]&st[i]))
        for(int j=0;st[j]<ST;++j){
            dp[0][i][j]=num[st[i]];
        }
    }
}

int dfs(int row,int r1,int r2){
    int &d=dp[row][r1][r2];
    if(row==0||d!=-1){
        return d;
    }
    d=0;
    if(row==1){
        for(int r3=0;st[r3]<ST;++r3){
            if(!(st[r1]&st[r2]) && dp[row-1][r2][r3]!=-1 &&!(marsh[row]&st[r1])){
                d=std::max(d,dfs(row-1,r2,r3)+num[st[r1]]);
            }
        }
        return d;
    }

    if(!(marsh[row-1]&st[r2]) && !(marsh[row]&st[r1])){
        for(int r3=0;st[r3]<ST;++r3){
            if(!(marsh[row-2]&st[r3])){
                if(!(st[r1]&st[r2]) && !(st[r2]&st[r3]) && !(st[r1]&st[r3])){
                    d=std::max(d,dfs(row-1,r2,r3)+num[st[r1]]);
                }
            }
        }
    }
    return d;
}
int main(){
    int k=0;
    for(int i=0;i<STATE;++i){
        if(!((i<<2)&i) && !((i<<1)&i))st[k++]=i;
        num[i]=get_bit1(i);
    }st[k]=STATE;
    while(scanf("%d%d",&n,&m)==2&&n){
        for(int i=0;i<n;++i)scanf("%s",tab[i]);
        init();
        int ans=0;
        for(int i=0;st[i]<ST;++i){
            for(int j=0;st[j]<ST;++j){
                ans=std::max(ans,dfs(n-1,i,j));
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
全部评论

相关推荐

01-02 21:17
已编辑
西安理工大学 后端
程序员小白条:项目不太重要,你的优势的算法竞赛,然后多背相关的八股文,项目可以不作为重点考虑,面试可能就简单带过项目就行了,你可以直接写简历,背项目相关的八股文就行,也不用自己做,时间紧张的情况下,性价比最高
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
正在热议
更多
# 听劝,这个简历怎么改 #
14086次浏览 182人参与
# 面试被问“你的缺点是什么?”怎么答 #
6359次浏览 98人参与
# 水滴春招 #
16350次浏览 346人参与
# 入职第四天,心情怎么样 #
11310次浏览 63人参与
# 租房找室友 #
8021次浏览 53人参与
# 读研or工作,哪个性价比更高? #
26152次浏览 356人参与
# 职场新人生存指南 #
199211次浏览 5509人参与
# 参加完秋招的机械人,还参加春招吗? #
26977次浏览 276人参与
# 文科生还参加今年的春招吗 #
4108次浏览 31人参与
# 简历无回复,你会继续海投还是优化再投? #
48624次浏览 561人参与
# 你见过最离谱的招聘要求是什么? #
144719次浏览 829人参与
# 如果重来一次你还会读研吗 #
155716次浏览 1706人参与
# 机械人选offer,最看重什么? #
69077次浏览 449人参与
# 选择和努力,哪个更重要? #
44292次浏览 493人参与
# 如果再来一次,你还会学硬件吗 #
103645次浏览 1245人参与
# 如果你有一天可以担任公司的CEO,你会做哪三件事? #
20520次浏览 413人参与
# 招聘要求与实际实习内容不符怎么办 #
46727次浏览 494人参与
# 22届毕业,是读研还是拿外包offer先苟着 #
4652次浏览 27人参与
# 你们的毕业论文什么进度了 #
901211次浏览 8960人参与
# 软开人,你觉得应届生多少薪资才算合理? #
81375次浏览 496人参与
# 国企还是互联网,你怎么选? #
109189次浏览 853人参与
牛客网
牛客企业服务