我们知道,我们可以使用二维数组求得一个DP问题的最佳值,但是并没有求得其最佳方案。
以背包问题为例,如何根据已经求得的二维数组 dp[N+1][W+1] ,求得最佳选择方案呢?
只需要看DP代码,如下:
int dpf[N+1][W+1]; //数组从0开始
int dp_solve()
{
for(int i=0; i<N;i++)
for(int j=0; j<=W;j++)
if(j<w[i])
dpf[i+1][j]=dpf[i][j];
else
dpf[i+1][j]=max(dpf[i][j],dpf[i][j-w[i]]+v[i]);
return dpf[N][W];
}
我们可以看到dpf[i+1][j] 进和 dpf[i][j],dpf[i][j-w[i]]+v[i] 两个状态相关。
【规则1】找出添加新步骤的关键条件。
而且,如果和dpf[i][j]相关,那么 最优价值不会变化,所以不会添加新步骤,所以我们只需要考虑 dpf[i][j] ==dpf[i-1][j-w[i-1]]+v[i-1] 的情况。(dpf 从N开始,而w,v数组从 N-1开始往前)
【小结】以上主要找出 使得最优价值发生改变的“那个步骤”,因为只有变化了,说明这个步骤才可能是最优策略里的一步。
【规则2】DP是正向进行的,求最优方案就该从逆向考虑。写出基本循环: