多维动态规划(SOJ 2818)
问题:给出$4$个状态$1,2,3,4$以及状态之间转移的费用矩阵
$T=\left[\begin{array}{cccc}0 &1 &2 &2\\ 1 &0 &1 &1\\ 2 &1 &0 &2\\ 2 &1 &2 &0 \end{array}\right]$.现有两个变量实现状态转移,这两个变量初始状态分别为$2,3$.给出一个状态序列$S$,求实现$S$所需的最小费用。
分析:动态规划题目。定义$i,j$分别为两个变量当前的状态,$k$为$S$的位置,$dp[i][j][k]$表示执行完$S$的前$k$个状态所花费的最小费用并且此时两个变量的状态分别为$i,j$.分析可知,$S$的第$k$个状态要么是第一个变量从$k-1$时刻转移而来,要么是第二个变量从$k-1$时刻转移而来,即$dp[i][j][k]$只可能是$dp[S[k]][j][k]$或$dp[i][S[k]][k]$.分别计算这两种情况即可。初始化$dp[2][3][0]=0$.
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstring> #include<algorithm> using namespace std; int dp[4][4][1000001]; char s[1000001]; int w[4][4] = { { 0, 1, 2, 2 }, { 1, 0, 1, 1 }, { 2, 1, 0, 2 }, { 2, 1, 2, 0 } }; int INF = 0x3f3f3f3f; int main() { int i, j, k; int len; int temp1, temp2; int ans; while (scanf("%s", s) == 1) { len = strlen(s); for (k = 0; k <= len; k++) for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) dp[i][j][k] = INF; dp[2][3][0] = 0; for (k = 1; k <= len; k++) { for (j = 0; j < 4; j++) { temp1 = INF; for (i = 0; i < 4; i++) if (dp[i][j][k-1]<INF) temp1 = min(temp1, dp[i][j][k - 1] + w[i][s[k - 1] - 48]); dp[s[k - 1] - 48][j][k] = temp1; } for (i = 0; i < 4; i++) { temp2 = INF; for (j = 0; j < 4; j++) if (dp[i][j][k-1]<INF) temp2 = min(temp2,dp[i][j][k-1]+w[j][s[k-1]-48]); dp[i][s[k-1] - 48][k] = temp2; } } ans = INF; for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) ans = min(ans, dp[i][j][len]); printf("%d\n", ans); } return 0; }