Day11 轮廓线 dp 插头 dp

I. 引入

[USACO06NOV] Corn Fields G

轮廓线 dp 入门题。

逐格枚举,考虑到未决策点仅会受到决策点与未决策点交界处点影响,引入轮廓线(这题是格子)。注意到 n n n 范围很小,状压。

f ( i , j , k ) f(i,j,k) f(i,j,k) 表示枚举到 ( i , j ) (i,j) (i,j) 轮廓线状态为 k k k 的方案数。

当前格 ( i , j ) (i,j) (i,j) 转移到下一格,考虑 ( i , j ) (i,j) (i,j) 填不填:

  • 上面已填, ( i , j ) (i,j) (i,j) 必不填,下一格轮廓线第 j j j 列改为 0 0 0

  • 左边已填或者 a ( i , j ) = 0 a(i,j)=0 a(i,j)=0 ( i , j ) (i,j) (i,j) 必不填,下一格轮廓线不变。

  • 其余情况填或不填均可,分别转移。

	f[1][1][0] = 1;
	for(int i=1; i<=n; i++)
	{
   
		for(int j=1; j<=m; j++)
		{
   
			int nxti, nxtj;
			(j == m) ? (nxti = i + 1, nxtj = 1) : (nxti = i, nxtj = j + 1);
			for(int k=0; k<=ALL; k++)
			{
   
				bool up = (1 << j-1) & k;
				bool left = (j == 1) ? 0 : (1 << j-2) & k;
				
				if(i == 1 and up) continue;
				
				if(up) 
					add(f[nxti][nxtj][k-(1<<j-1)], f[i][j][k]);
					
				else if(left or !a[i][j]) 
					add(f[nxti][nxtj][k], f[i][j][k]);
					
				else 
					add(f[nxti][nxtj][k], f[i][j][k]), 
					add(f[nxti][nxtj][k+(1<<j-1)], f[i][j][k]);
			}
		}
	}

代码

注意到每次转移只与上一格有关,考虑滚动数组。代码

HDU Eat the Trees

插头 dp 入门题。

引入了插头的概念,插头有上下左右四种,通过插头可以保证连通性。

当前格 ( i , j ) (i,j) (i,j) 转移到下一格:

  • ( i , j ) (i,j)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值