题目
详见题目uva1291
解题思路
就题面略长,枚举所有状态,DP暴力转移即可。
(转移的时候不一定只转移合法状态,也可以所有状态都转移完以后,把不合法状态筛去。)
代码
#include <bits/stdc++.h>
using namespace std;
int dp[1000010][6][6];
//dp[i][j][k] 前i个动作,左脚在j上, 右脚在k上的最小花费
int a[1000010];
int f(int x, int y) //计算花费
{
if (x == y)
return 1;
if (x == 0)
return 2;
if (abs(x - y) == 2)
return 4;
return 3;
}
int n;
void solve()
{
int temp;
while (cin >> temp && temp)
a[++n] = temp;
memset(dp, 0x3f3f3f3f, sizeof dp);
dp[0][0][0] = 0;
for (int i = 1; i <= n; i++)
{
for (int r = 0; r <= 4; r++) //移动左脚
for (int prel = 0; prel <= 4; prel++)
for (int nowl = 0; nowl <= 4; nowl++)
dp[i][nowl][r] = min(dp[i][nowl][r], dp[i - 1][prel][r] + f(prel, nowl));
for (int l = 0; l <= 4; l++) // 移动右脚
for (int prer = 0; prer <= 4; prer++)
for (int nowr = 0; nowr <= 4; nowr++)
dp[i][l][nowr] = min(dp[i][l][nowr], dp[i - 1][l][prer] + f(prer, nowr));
for (int r = 0; r <= 4; r++) //将不符合条件的筛去
for (int l = 0; l <= 4; l++)
if (l != a[i] && r != a[i])
dp[i][l][r] = 0x3f3f3f3f;
}
int ans = 0x3f3f3f3f;
for (int l = 0; l <= 4; l++)
for (int r = 0; r <= 4; r++)
ans = min(ans, dp[n][l][r]);
cout << ans << endl;
}
int main()
{
int temp;
while (cin >> temp && temp)
{
n = 0;
a[++n] = temp;
solve();
}
return 0;
}