牧场的安排(状压DP入门)

Posted shallow-dream

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牧场的安排(状压DP入门)相关的知识,希望对你有一定的参考价值。

技术图片

技术图片

 

:将每行输入的数字转换为十进制,然后预处理出所有满足题意的状态并存储于 sta ,再处理出单独一行时候的方案数并存储于 dp1,sta  枚举第 i 行的状态,判断第 j = i-1行的状态,并更新dpi , j ,最后累和即可

技术图片
#include <bits/stdc++.h>
using namespace std;
#define ll long long
using namespace std;
const int mod = 1e8;/// 998244353;
const int mxn = 15 +7;
ll _,m,n,t,k,ans;
int dp[mxn][1<<13] , a[mxn][mxn] , f[mxn] , sta[1<<13] ;
void solve()
{
    while(cin>>m>>n){
        memset(f,0,sizeof(f));
        memset(sta,0,sizeof(sta));
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=m;i++){ /// 
            for(int j=1;j<=n;j++){
                cin>>a[i][j];
                f[i] = (f[i]<<1) + a[i][j];
            }
        }
        ll last = (1<<n);
        for(int i=0;i<last;i++){ /// 
            if(( (i&(i<<1))==0) && ((i&(i>>1))==0) )
                sta[i] = 1 ;
        }
        for(int i=0;i<last;i++){/// 状态合理 , 输入满足状态
            if(sta[i]==1 && ( (i&f[1]) ==i ) )
                dp[1][i] = 1 ;
        }
        for(int i=2;i<=m;i++){
            for(int j=0;j<last;j++){
                if(sta[j]==1 && ( (f[i] & j) == j) ){
                    for(int k=0;k<last;k++) /// i-1 行状态
                        if((j&k)==0)
                            dp[i][j] = (dp[i][j]+dp[i-1][k])%mod;
                }
            }
        }
        ans = 0 ;
        for(int i=0;i<last;i++)
            ans = (ans+dp[m][i])%mod;
        cout<<ans<<endl;
    }
}
int main()
{
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    solve();
}
AC

 

以上是关于牧场的安排(状压DP入门)的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ1725[Usaco2006 Nov]Corn Fields牧场的安排 状压DP

bzoj1725/Usaco2006 NovCorn Fields牧场的安排——状压dp

状压DPBZOJ 1725 Usaco Corn Fields牧场的安排

状压dp入门

状压DPCorn Fields牧场的安排

BZOJ1725: [Usaco2006 Nov]Corn Fields牧场的安排