P1541

Posted strategist-614

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1541相关的知识,希望对你有一定的参考价值。

P1541

考虑 (DP)

首先考虑 (DP) 的状态表示:(dp[a][b][c][d]) 表示 走 (1) 格还剩 (a) 个,走 (2) 格还剩 (b) 个,走 (3) 格还剩 (c) 个,走 (4) 个还剩 (d) 个最大的权值和。

那么在当前状态下在还能走的情况下可以走一格,两格,三格,四格。

所以考虑记忆化搜索,思维难度较小。

(dp[a][b][c][d] = max(dp[a - 1][b][c][d],dp[a][b - 1][c][d],dp[a][b][c - 1][d],dp[a][b][c][d - 1])) 同时 (a geq 1,b geq 1,c geq 1,d geq 1)

当前的所在位置是 int pos = 1 + (a0 - a) + (a1 - b) * 2 + (a2 - c) * 3 + (a3 - d) * 4;

最终算出答案。

我的代码有点妖娆,大概思路就是不累加当前所在位置的权值,而是算下一个能够到达的位置的权值,这样算就少算了开始的第一个位置的值,最后要加上去。

#include <bits/stdc++.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define rep(I, N) for (int I = 1; I <= (N); ++I)
#define repp(I, N) for (int I = 0; I < (N); ++I)
#define FOR(I, A, B) for (int I = (A); I <= (B); ++I)
#define FORR(I, A, B) for (int I = (A); I >= (B); I--)
#define SORT_UNIQUE(c) (sort(c.begin(), c.end()), c.resize(distance(c.begin(), unique(c.begin(), c.end()))))
#define GET_POS(c, x) (lower_bound(c.begin(), c.end(), x) - c.begin())
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define F first
#define S second
using namespace std;
const int N = 350 + 5;
const int M = 45;
const double eps = 1e-7;
const int mod = 1e9 + 7;
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
typedef pair<int, int> PII;
typedef vector<int> VI;
typedef vector<LL> VL;
typedef vector<PII> VPII;
typedef pair<LL, LL> PLL;
typedef vector<PLL> VPLL;
int ax[N], b[N];
int dp[M][M][M][M];
int a0 = 0, a1 = 0, a2 = 0, a3 = 0;
int n, m;
int dfs(int a, int b, int c, int d)
{
    if (dp[a][b][c][d] != -1)
        return dp[a][b][c][d];
    int ans = 0;
    int pos = 1 + (a0 - a) + (a1 - b) * 2 + (a2 - c) * 3 + (a3 - d) * 4;//算位置
    if (a >= 1)
    {
        ans = max(ans, dfs(a - 1, b, c, d) + ax[pos + 1]);// (a-1,b,c,d)表示位置的权值,下同
    }
    if (b >= 1)
        ans = max(ans, dfs(a, b - 1, c, d) + ax[pos + 2]);
    if (c >= 1)
        ans = max(ans, dfs(a, b, c - 1, d) + ax[pos + 3]);
    if (d >= 1)
        ans = max(ans, dfs(a, b, c, d - 1) + ax[pos + 4]);
    return (dp[a][b][c][d] = ans);
}
int main()
{
    cin >> n >> m;
    rep(i, n) cin >> ax[i];
    rep(i, m) cin >> b[i];
    memset(dp, -1, sizeof dp);
    rep(i, m)
    {
        if (b[i] == 1)
            a0++;
        else if (b[i] == 2)
            a1++;
        else if (b[i] == 3)
            a2++;
        else
            a3++;
    }
    cout << dfs(a0, a1, a2, a3) + ax[1] << endl;//加上第一个位置的值
    return 0;
}

以上是关于P1541的主要内容,如果未能解决你的问题,请参考以下文章

luogu P1541 乌龟棋 题解

codevs1068 乌龟棋==洛谷P1541 乌龟棋

洛谷P1541 乌龟棋 [2010NOIP提高组]

P1541 乌龟棋

P1541 乌龟棋

P1541 乌龟棋