P1879 [USACO06NOV]玉米田Corn Fields

本文深入解析状压动态规划(DP)的概念与应用,通过具体实例讲解如何使用状压DP解决复杂问题,包括状态表示、状态转移方程及代码实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

状压dp还不熟啊。。。


这是状压dp例题后面的基础练习题了。可以看“互不侵犯”这道题。

状态表示方法类似,只不过没有第三维即数量的限制:设\(dp[i][j]\)为前\(i\)行,第\(i\)行状态为\(j\)时的方案数。

状态转移方程简直不能再简单:\(dp[i][k] = sum(dp[i - 1][j])\),其中\(j\)是上一行的状态。

首先当然预处理,减小重复的筛除不合法时间。

这道题的限制条件是任意两片田不能相邻,即上下左右不能有田。

左右的容易解决,拿自己和自己左移一位\(and\)一下即可。

上下的在递推的时候更容易解决,直接\(and\)

注意:二进制运算的优先级很低,非常低,所以有二进制的时候一定要打好括号!!!

代码:

#include<cstdio>

const int maxn = 14;
const int mod = 100000000;
int n, m;
long long dp[maxn][1 << maxn];
int status[1 << maxn], tot;
int check[maxn];
long long ans;
int maxl;
void init()
{
    
}
int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            int temp; scanf("%d", &temp);
            check[i] = check[i] << 1 | temp;
        }
    }
    maxl = 1 << m;
    for(int i = 0; i < maxl; i++)
    {
        if(!(i & (i << 1)))
        {
            status[++tot] = i;
            if((i & check[1]) == i)
            {
                dp[1][i] = 1;
            }
        }
    }
    //for(int i = 1; i <= tot; i++) printf("%d\n", dp[1][status[i]]);
    
    for(int i = 2; i <= n; i++)
    {
        for(int j = 1; j <= tot; j++)
        {
            for(int k = 1; k <= tot; k++)
            {
                if((status[j] & check[i - 1]) != status[j]) continue;
                if((status[k] & check[i]) != status[k]) continue;
                if(status[j] & status[k]) continue;
                
                dp[i][status[k]] = (dp[i][status[k]] + dp[i - 1][status[j]]) % mod;
            }
        }
    }
    for(int i = 1; i <= tot; i++) ans = (ans + dp[n][status[i]]) % mod;
    printf("%lld\n", ans);
    return 0;
}

转载于:https://www.cnblogs.com/Garen-Wang/p/9532487.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值