dp:数组平移

$dp$时,如果需要用负数作为数组下标,可以考虑数组平移。我的方法是声明常量P,把可能有负数的下标位置上的变量加上P,使得该变量在任何可能情况下都为非负整数。

例如:洛谷P1282-多米诺骨牌。$dp$时这样写:

1
2
3
for (int i = 2; i <= n; i++)
for (int j = -5000; j <= 5000; j++)
dp[i][j + P] = min(dp[i - 1][j - (b[i] - a[i]) + P] + 1, dp[i - 1][j - (a[i] - b[i]) + P]);

其中$dp$数组的第二维需要平移,且我们知道它的范围为$-5000$至$5000$。因此声明一个常量const int P = 5010,在第二维上加上$P$。