• 【思维】状压dp—— 2020 联想杯 M


    这个状压还要输出方案实在是太ex了

    第 i 行放完了水后,能新种下的甘蔗数量取决于 i − 1 行和 i − 2 行 的状态

    令 dp【i,j】 表示放完前 i 行且最后两行状态为 j 时最多能种下的数量

    我们在第 i 行放水有可能能使 i − 1 行的某个格子能够放上甘蔗了, 但如果不知道 i − 2 行的状态的话是没办法确定该格子是否已经被 放过了的

    决策就是枚举第 i 行水是如何放的

    #include "bits/stdc++.h"
    #define hhh cerr<<"hhh"<<endl
    #define see(x) cerr<<(#x)<<'='<<(x)<<endl
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pr;
    inline int read() {int x=0,f=1;char c=getchar();while(c!='-'&&(c<'0'||c>'9'))c=getchar();if(c=='-')f=-1,c=getchar();while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();return f*x;}
    
    const int maxn = 3e5+7;
    const int inf = 0x3f3f3f3f;
    const int mod = 1e9+7;
    
    int n, m;
    int dp[33][256][256], from[33][256][256];
    char mp[33][10];
    string res[33];
    
    int main() {
        n=read(), m=read();
        for(int i=0; i<n; ++i) scanf("%s", mp[i]);
        memset(dp,-1,sizeof(dp));
        memset(from,-1,sizeof(from));
        if(n==1) {
            int ans=-1, state=-1;
            for(int s=0; s<1<<m; ++s) {
                int tmp=0;
                for(int j=0; j<m; ++j) {
                    if(!(s>>j&1)) {
                        tmp++;
                        if(mp[0][j]=='.') {
                            int f=0;
                            if(j>0&&(s>>(j-1)&1)) f=1;
                            else if(j<m-1&&(s>>(j+1)&1)) f=1;
                            if(!f) { tmp=-1; break; }
                        }
                    }
                    else if(mp[0][j]=='#') { tmp=-1; break; }
                }
                if(tmp<0) continue;
                if(tmp>ans) ans=tmp, state=s;
            }
            for(int i=0; i<m; ++i) {
                if(state>>i&1) printf("O");
                else if(mp[0][i]=='#') printf("#");
                else printf("X");
            }
            puts("");
            return 0;
        }
        for(int s=0; s<1<<m; ++s) {
            for(int s1=0; s1<1<<m; ++s1)  {
                int tmp=0;
                for(int j=0; j<m; ++j) {
                    if(!(s>>j&1)) tmp++;
                    else if(mp[1][j]=='#') { tmp=-1; break; }
                }
                if(tmp<0) continue;
                for(int j=0; j<m; ++j) {
                    if(!(s1>>j&1)) {
                        tmp++;
                        if(mp[0][j]=='.') {
                            int f=0;
                            if(j>0&&s1>>(j-1)&1) f=1;
                            else if(j<m-1&&s1>>(j+1)&1) f=1;
                            else if(s>>j&1) f=1;
                            if(!f) { tmp=-1; break; }
                        }
                    }
                    else if(mp[0][j]=='#') { tmp=-1; break; }
                }
                dp[1][s][s1]=tmp;
            }
        }
        for(int i=2; i<n; ++i) {
            for(int s=0; s<1<<m; ++s) {
                int tmp=0;
                for(int j=0; j<m; ++j) {
                    if(!(s>>j&1)) tmp++;
                    else if(mp[i][j]=='#') { tmp=-1; break; }
                }
                if(tmp<0) continue;
                for(int s1=0; s1<1<<m; ++s1) {
                    int f=1;
                    for(int j=0; j<m; ++j) {
                        if(!(s1>>j&1)) ;
                        else if(mp[i-1][j]=='#') { f=0; break; }
                    }
                    if(!f) continue;
                    int mx=-1, state=-1;
                    for(int s2=0; s2<1<<m; ++s2) if(dp[i-1][s1][s2]>=0) {
                        int f1=1;
                        for(int j=0; j<m; ++j) {
                            if(!(s1>>j&1)&&mp[i-1][j]=='.') {
                                int f=0;
                                if(j>0&&(s1>>(j-1)&1)) f=1;
                                else if(j<m-1&&(s1>>(j+1)&1)) f=1;
                                else if(s>>j&1) f=1;
                                else if(s2>>j&1) f=1;
                                if(!f) { f1=0; break; }
                            }
                        }
                        if(f1&&dp[i-1][s1][s2]>mx) {
                            mx=dp[i-1][s1][s2];
                            state=s2;
                        }
                    }
                    if(mx>=0) {
                        dp[i][s][s1]=tmp+mx;
                        from[i][s][s1]=state;
                    }
                }
            }
        }
        int mx=-1, state=-1, state1=-1;
        for(int s=0; s<1<<m; ++s) {
            for(int s1=0; s1<1<<m; ++s1) if(dp[n-1][s][s1]>=0) {
                int f1=1;
                for(int j=0; j<m; ++j) {
                    if(!(s>>j&1)&&mp[n-1][j]=='.') {
                        int f=0;
                        if(j>0&&(s>>(j-1)&1)) f=1;
                        else if(j<m-1&&(s>>(j+1)&1)) f=1;
                        else if(s1>>j&1) f=1;
                        if(!f) { f1=0; break; }
                    }
                }
                if(f1&&dp[n-1][s][s1]>mx) {
                    mx=dp[n-1][s][s1];
                    state=s;
                    state1=s1;
                }
            }
        }
        int s=state, s1=state1;
        for(int i=n-1; i>1; --i) {
            for(int j=0; j<m; ++j) {
                if(s>>j&1) res[i]+='O';
                else if(mp[i][j]=='#') res[i]+='#';
                else res[i]+='X';
            }
            int s2=from[i][s][s1];
            s=s1, s1=s2;
        }
        for(int j=0; j<m; ++j) {
            if(s>>j&1) res[1]+='O';
            else if(mp[1][j]=='#') res[1]+='#';
            else res[1]+='X';
        }
        s=s1;
        for(int j=0; j<m; ++j) {
            if(s>>j&1) res[0]+='O';
            else if(mp[0][j]=='#') res[0]+='#';
            else res[0]+='X';
        }
        for(int i=0; i<n; ++i) cout<<res[i]<<endl;
    }
  • 相关阅读:
    Java成神之路技术整理(长期更新)
    WEB攻击手段及防御第1篇-XSS
    JSON是什么,为什么这么流行?
    常用的 7 款 MySQL 客户端工具,你值得拥有!
    Spring的核心思想,总结得非常好!
    到底什么级别才算是高并发?
    非常详尽的 Shiro 架构解析
    7 种 JVM 垃圾收集器,看完我跪了。。
    电商那些年,我摸爬打滚出的高并发架构实战干货
    Spring Boot 把 Maven 干掉了,拥抱 Gradle!
  • 原文地址:https://www.cnblogs.com/zsben991126/p/13032641.html
Copyright © 2020-2023  润新知