P1541 乌龟棋 暴力DP

第i个位置的分数是 a[i]。

每次可使用一张卡牌移动一定距离,每到一个位置可以加一次分数

问到终点的最大分数。

由于每张卡牌上限不超过40,考虑将状态设置为当前该种卡使用的卡牌数。

DP[a][b][c][d]表示使用a张1号牌,b张2号牌,c张3号牌,d张4号牌的情况下能够得到的最大分数。

考虑用记忆化搜索实现。

#pragma warning(disable:4996)

#include<iostream>
#include<algorithm>
#include<bitset>
#include<tuple>
#include<unordered_map>
#include<fstream>
#include<iomanip>
#include<string>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<stack>
#include<sstream>
#include<cstdio>
#include<ctime>
#include<cstdlib>
#define pb push_back
#define INF 0x3f3f3f3f
#define inf 0x7FFFFFFF
#define moD 1000000003
#define pii pair<ll,ll>
#define eps 1e-8
#define equals(a,b) (fabs(a-b)<eps)
#define bug puts("bug")
#define re  register
#define fi first
#define se second
typedef  long long ll;
typedef unsigned long long ull;
const ll MOD = 1e6 + 7;
const int maxn = 2e4 +5;
const double Inf = 10000.0;
const double PI = acos(-1.0);
using namespace std;

ll mul(ll a, ll b, ll m) {
    ll res = 0;
    while (b) {
        if (b & 1) res = (res + a) % m;
        a = (a + a) % m;
        b >>= 1;
    }
    return res % m;
}

ll quickPower(ll a, ll b, ll m) {
    ll base = a;
    ll ans = 1ll;
    while (b) {
        if (b & 1) ans = mul(ans, base , m);
        base = mul(base, base , m);
        b >>= 1;
    }
    return ans;
}


int readint() {
    int x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}

ll readll() {
    ll x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}

void Put(int x)  {
    if (x > 9) Put(x / 10);
    putchar(x % 10 + '0');
}

int n, m;
int g[5];
int dp[42][42][42][42];
int a[355];


int dfs(int n1, int n2, int n3, int n4) {
    if (dp[n1][n2][n3][n4]) return dp[n1][n2][n3][n4];
    int cur = 1 + n1 + n2 * 2 + n3 * 3 + n4 * 4;
    int now = 0;
    if (g[1] == n1 && g[2] == n2 && g[3] == n3 && g[4] == n4) return 0;
    if (g[1] > n1) now = max(now, dfs(n1 + 1, n2, n3, n4) + a[cur + 1]);
    if (g[2] > n2) now = max(now, dfs(n1, n2 + 1, n3, n4) + a[cur + 2]);
    if (g[3] > n3) now = max(now, dfs(n1, n2 , n3 + 1, n4) + a[cur + 3]);
    if (g[4] > n4) now = max(now, dfs(n1, n2 , n3, n4 + 1) + a[cur + 4]);
    return dp[n1][n2][n3][n4] = now;
}



int main() {
    int tmp;
    n = readint(), m = readint();
    for (int i = 1; i <= n; i++) a[i] = readint();
    for (int i = 0; i < m; i++)  tmp = readint(), g[tmp]++;
    dp[0][0][0][0] = a[1];
    int res = 0;
    if (g[1]) res = max(res, dfs(1, 0, 0, 0) + a[2]);
    if (g[2]) res = max(res, dfs(0, 1, 0, 0) + a[3]);
    if (g[3]) res = max(res, dfs(0, 0, 1, 0) + a[4]);
    if (g[4]) res = max(res, dfs(0, 0, 0, 1) + a[5]);
    Put(res + a[1]);
}

 

上一篇:为什么安装了增强功能,VirtualBox菜单自动调整显示尺寸还是灰色,不能用


下一篇:Codeforces Round #635 (Div. 2) D-Xenia and Colorful Gems 二分