多维动态规划(SOJ 2818)

SOJ 2818: QQ音速

问题:给出$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$. 

代码:

#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;
}
View Code

posted on 2019-03-21 04:36  小叶子曰  阅读(424)  评论(0编辑  收藏  举报

导航