状压DP入门NO.1洛谷 P1879玉米地

本文介绍了一种使用状态压缩动态规划(状压DP)解决特定种植问题的方法。通过预处理土地状态,避免左右冲突,并迭代更新每行的种植状态,最终计算出所有可能的种植方案数。该算法适用于处理具有特定约束条件的二维矩阵问题。

题目链接

Code:

//2018-09-17 提高+
//状压dp 
#include<iostream>
#include<cstdio>
#define mod 100000000

using namespace std;

long long n,m,ans;
int map[13][13];
long long f[1<<12][13];
int y[13],sign[1<<12];

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			scanf("%d",&map[i][j]);
			//记录土地情况 
	
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			y[i]=(y[i]<<1)+map[i][j];
			//合并土地情况
			//方便后面判断 
	
	//枚举每一种状态 
	//预处理左右不行的状态 
	for(int i=0;i<(1<<m);i++)
	{
		if(!(i&(i<<1)) && !(i&(i>>1)))
		{
			sign[i]=1;
			//标记 
			if((i&y[1]) == i) f[i][1]=1;
			//如果这种状态符合土地条件
			//初始化f数组 
		}
	}
	
	for(int i=2;i<=n;i++)
	//枚举每一行 
		for(int j=0;j<(1<<m);j++)
		//枚举上一行的状态 
			if(((j&y[i-1])==j) && sign[j])
			//如果土地肥沃,且当前状态左右不冲突 
				for(int k=0;k<(1<<m);k++)
				//枚举这一行的状态 
					if(((k&y[i])==k)&&!(j&k)&&sign[k])
						f[k][i]=(f[k][i]+f[j][i-1])%mod;
						//当前行的状态只会收上一行的影响 
	
	for(int i=0;i<(1<<m);i++) ans=(ans+f[i][n])%mod;
	//记录答案 
	
	cout<<ans;
	
	return 0;
}
//By Yfengzi 
### 关于缩动态规划(DP)的相关题目与教程 #### 洛谷平台上的资源推荐 洛谷作为一个优质的在线编程练习网站,提供了大量有关缩动态规划的学习资料和实战题目。对于想要深入理解并掌握这一复杂算法的人来说,这些资源非常有价值。 #### 推荐的经典入门题库 - **P1433 吃奶酪**:这道题不仅涉及到了深度优先搜索加缩的思想,还融合了动态规划的概念,在解决过程中能够很好地锻炼选手对多种算法组合运用的能力[^2]。 - **PRZ - POI2004**:此问题同样是一道典型的缩动态规划应用实例,通过该题目的训练可以帮助加深对这类问题处理方法的理解[^3]。 #### 学习路径建议 为了更好地理解和实践缩动态规划,建议按照如下顺序逐步推进: - 熟悉二进制位运算操作的基础知识,这是实现高效编码的关键技能之一; - 复习基本的动态规划理论及其常见应用场景; - 结合具体案例研究如何定义合适的态表示形式以及设计有效的态转移方程; ```python def dp_solution(): """ 这里提供了一个简化版的缩动态规划框架, 实际编写时需根据具体问题调整参数设置及逻辑流程。 """ n = ... # 输入规模大小 state_size = 1 << n # 总共可能存在的不同态数 # 初始化记忆化数组,默认值设为无穷大或其他不可能取到的最大/最小边界条件 memo = [-1] * state_size def dfs(current_state, current_index): nonlocal memo if all_bits_set(current_state): return cost_to_end[current_index] if memo[current_state] != -1: return memo[current_state] min_cost = float('inf') for next_index in range(n): new_state = update_state_with_next_move(current_state, next_index) transition_cost = calculate_transition_expense(current_index, next_index) total_cost = transition_cost + dfs(new_state, next_index) min_cost = min(min_cost, total_cost) memo[current_state] = min_cost return min_cost result = dfs(initial_state(), start_position()) return result ``` 上述代码片段展示了利用函数`dfs()`来进行带备忘录的记忆化搜索过程,其中包含了几个重要的组成部分如初始化全局变量、判断终止条件、剪枝优化等技巧来提高求解效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值