洛谷P1541 乌龟棋
题目链接
卡片只有四张,并且我们要知道使用完某张牌之后得到的积分,所以我们要去枚举所有的情况,因为牌的种类数比较少,所以我们可以开四维数组去暴力枚举所有的状态,并且在每一次从前一种状态走到下一个位置的时候,要及时更新,题目要求的是求出最大值这个属性,所以在转移的时候我们只需要去维护最大值这个性质就可以了,所以我们的状态转移方程就是$$dp[i] = \max (dp[i], dp[i - 1] + a[i])$$
#include <bits/stdc++.h>
using i64 = long long;
#define rep(i, a, n) for (int i = a; i < n; i ++ )
#define per(i, a, n) for (int i = n - 1; i >= a; i -- )
#define SZ(a) (int(a.size()))
#define pb push_back
#define all(a) a.begin(), a.end()
//head
constexpr int N = 1010;
int n, m;
int a[N], cnt[5];
int dp[50][50][50][50];
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i ++ ) scanf("%d", a + i);
rep(i,0,m) {
int x; scanf("%d", &x);
cnt[x] ++;
}
dp[0][0][0][0] = a[1];
for (int i = 0; i <= cnt[1]; i ++ )
rep(j, 0, cnt[2] + 1)
rep(k, 0, cnt[3] + 1)
rep(t, 0, cnt[4] + 1) {
int cur = 1 + i * 1 + j * 2 + k * 3 + t * 4;
if (!i && !j && !t && !k) continue;
if (i) dp[i][j][k][t] = std::max(dp[i][j][k][t], dp[i - 1][j][k][t] + a[cur]);
if (j) dp[i][j][k][t] = std::max(dp[i][j][k][t], dp[i][j - 1][k][t] + a[cur]);
if (k) dp[i][j][k][t] = std::max(dp[i][j][k][t], dp[i][j][k - 1][t] + a[cur]);
if (t) dp[i][j][k][t] = std::max(dp[i][j][k][t], dp[i][j][k][t - 1] + a[cur]);
}
printf("%d\n", dp[cnt[1]][cnt[2]][cnt[3]][cnt[4]]);
return 0;
}

浙公网安备 33010602011771号