关于处理使用dp时出现后效性问题的解决方法
P1006 [NOIP2008 提高组] 传纸条 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
P1004 [NOIP2000 提高组] 方格取数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
作为刚做得两道题,均用的是dp,而且是四维;
题目都有 “一个图两次遍历但便利时会改变本身” 的问题,这就产生了后效性,不满足dp的执行前提;
若只是两次dp,达不到最优解;
引用:为什么四维dp两个点要同时走,不能一次走一个? - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
第一次走的最优解并不一定能使两次走的值最大
给你这个数据
0 0 2 3 0 0 0
0 0 3 0 0 0 0
0 0 3 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 4 0 0
0 0 0 0 4 0 0
0 0 2 0 4 0 0
第一次走
0 0 0 0 0 0 0
0 0 3 0 0 0 0
0 0 3 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 2 0 0 0 0
第二次取完 如果按照你说的每一次都是最优解,第一次走
0 0 0 3 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 2 0 0 0 0
那么你最后会剩一个2没有取走。
而通过观察可以发现,是有方法两次取走所有数的
所以需要四维dp,本质上是将两次dp同时进行,将原来两个分开的dp之间可能产生的“后效性”“扭在一起”(不会表达啊啊啊大悲)
怎么处理呢?
对于第一题传纸条
if(x1==x2&&y1==y2){ continue; }
但对于第二题方格取数
if(x1==x2&&y1==y2){ dp[x1][y1][x2][y2]-=Map[x1][y1];//Map[x2][y2]也行 }
判断条件是一致的;
第一题是跳过,因为这个点被访问后就不能再被二次访问了;
第二题是减去一次赋值,因为在这时这个已经被取过的点可以被二次访问,同时提供继续遍历;(意会一下,表达不出来(悲)