1. 程式人生 > 實用技巧 >P1541 烏龜棋 暴力DP

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]); }