Codeforces Beta Round 96 (Div. 1) -- C. Logo Turtle (dp,记忆化搜索)

记忆化搜索

就是暴力,多一步优化,走过的路别走了。说实话,可能是数据水了,居然能过。

const int N = 510;
string s;
int n, ans;
bool st[501][501][2][50];

void dfs(int x, int idx, int dir, int k)
{
	if (st[x][idx][dir][k]) return;
	st[x][idx][dir][k] = 1; //走过的路不走了
	
	if (x == s.size()) 
	{
		if (k % 2 == 0) ans = max(ans, abs(idx));
		else ans = max(ans, abs(abs(idx) - 1));
		return;
	}
	if (s[x] == 'F')
	{
		if (k > 0) dfs(x + 1, idx, dir ^ 1, k - 1);
		if (dir == 0) dfs(x + 1, idx + 1, dir, k);
		else dfs(x + 1, idx - 1, dir, k);
	}
	else 
	{
		if (k > 0) 
		{
			if (dir == 0) dfs(x + 1, idx + 1, dir, k - 1);
			else dfs(x + 1, idx - 1, dir, k - 1);
		}
		dfs(x + 1, idx, dir ^ 1, k);
	}
}
void solve()
{
    cin >> s >> n;
    dfs(0, 0, 0, n);
    cout << ans << '\n';
}

dp写法

int dp[N][N][2];

void solve()
{
	cin >> cmd >> n;
	int len = cmd.size();
	cmd = ' ' + cmd;
	for (int i = 0; i <= len; i++)
        for (int j = 0; j <= n; j++) dp[i][j][0] = dp[i][j][1] = -0x3f3f3f;
    dp[0][0][0] = 0;//正方向
    dp[0][0][1] = 0;//负方向,两边都可以走
    for (int i = 1; i <= len; i++)
    {
        for (int j = 0; j <= n; j++)
        {
            for (int k = 0; k <= j; k++)
            {
                if (cmd[i] == 'F')
                {
                    if (k & 1)
                    {
                        dp[i][j][0] = max(dp[i][j][0], dp[i - 1][j - k][1]);
                        dp[i][j][1] = max(dp[i][j][1], dp[i - 1][j - k][0]);
                    }
                    else
                    {
                        dp[i][j][0] = max(dp[i][j][0], dp[i - 1][j - k][0] + 1);
                        dp[i][j][1] = max(dp[i][j][1], dp[i - 1][j - k][1] - 1);
                    }
                }
                else
                {

                    if (k & 1)
                    {
                        dp[i][j][0] = max(dp[i][j][0], dp[i - 1][j - k][0] + 1);
                        dp[i][j][1] = max(dp[i][j][1], dp[i - 1][j - k][1] - 1);
                    }
                    else
                    {
                        dp[i][j][0] = max(dp[i][j][0], dp[i - 1][j - k][1]);
                        dp[i][j][1] = max(dp[i][j][1], dp[i - 1][j - k][0]);
                    }
                }
            }

        }
    }
    cout << max(dp[len][n][0], dp[len][n][1]) << '\n';
}
posted @ 2023-04-24 14:01  N再再  阅读(22)  评论(0)    收藏  举报