刚学插头dp,全输出0求调
查看原帖
刚学插头dp,全输出0求调
537998
lpx2024楼主2023/8/9 17:54
#include<bits/stdc++.h>
using namespace std;
bool mp[14][14],dp[14][14][16500];
signed main(){
    int t,n,m;
    cin>>t;
    while(t--){
        cin>>n>>m;
        memset(dp,0,sizeof(dp));
        dp[0][m][0]=1;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++) cin>>mp[i][j];
        }
        for(int i=i;i<=n;i++){
            for(int k=0;k<1<<m;k++) if(k&1==0) dp[i+1][1][k]=dp[i][m][k];
            for(int j=1;j<=m;j++){
                if(!mp[i][j]){//地图不可用,左无上无变左无上无,其他清空
                    for(int k=0;k<1<<m;k++){
                        if(k&1==0 && k&1<<j==0){
                            dp[i][j+1][k]+=dp[i][j][k];
                        } else dp[i][j][k]=0;
                    }
                } else {
                    for(int k=0;k<1<<m;k++){
                        if(k&1==0){//左侧没插头
                            if(k&1<<j==0){//上方没插头
                                if(i!=n && j!=m) dp[i][j+1][k+(1<<j)+1]+=dp[i][j][k];//左无上无变左有上有
                            } else {
                                if(i!=n) dp[i][j+1][k]+=dp[i][j][k];//左无上有变左无上有
                                if(j!=m) dp[i][j+1][k-(1<<j)+1]+=dp[i][j][k];//左无上有变左有上无
                            }
                        } else {
                            if(k&1<<j==0){
                                if(j!=m) dp[i][j+1][k]+=dp[i][j][k];//左有上无变左有上无
                                if(i!=n) dp[i][j+1][k+(1<<j)-1]+=dp[i][j][k];//左有上无变左无上有
                            } else {
                                dp[i][j+1][k-(1<<j)-1]+=dp[i][j][k];//左有上有变左无上无
                            }
                        }
                     }
                }
            }
        }
        cout<<dp[n][m][0]<<endl;
    }
    return 0;
}
2023/8/9 17:54
加载中...