高维前缀和与子集DP(SOSDP)

从二维前缀和的另一种方法谈起

求二维前缀和的常用方法为容斥,但对于高维前缀和,容斥的效率显然是不够优秀的。

因此,我们可以考虑从不同维度来进行转移,每次只转移一个维度。

for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) s[i][j]+=s[i-1][j];
for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) s[i][j]+=s[i][j-1];

如何理解?图上的红色箭头表示第一维的转移,蓝色箭头表示第二维的转移。容易发现,由于我们先后进行了两种颜色箭头的转移,所以对于一个节点,其左上角的所有节点都可以通过向下若干次转移,并向右若干次来到该节点,而其他节点则无法转移至此,因此该算法的正确性可以得到保证。

在这里插入图片描述
若推广至 n n n 维,只需先枚举维数,再进行转移即可。

适用范围

高维前缀和(基于DP的前缀和)适用于求解类似 ∑ i ⊆ k a i \sum\limits_{i\subseteq k}a_i ikai 的问题,其中求和运算可以改为任意可合并的操作,如 max ⁡ , min ⁡ \max,\min max,min 等。

具体问题中,一般会运用二进制数进行状态压缩。

for (int j=0;j<n;j++) // 维数 
		for (int i=1;i<(1<<n);i++)
			if ((i>>j)&1) f[i]+=f[i^(1<<j)];

例题

  • 32
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值