AcWing 312. 乌龟棋 (简单DP)打卡

题目:https://www.acwing.com/problem/content/description/314/

题意:有一段路,每个格子都有个价值,然后有m张卡牌,四种类型,走1,2,3,4步,然后输入保证正好把所有卡牌用完到达终点,求最大价值

思路:保证全部用完,只是顺序不一样得到的价值不一样,首先分别是四种类型的卡牌,对于这种要在一个点找最优的肯定是dp,我开始想的是五维状态  dp[n][a][b][c][d],代表第n个格子,然后a,b,c,d四种类型卡牌的数量, 然后代表我用a,b,c,d类型这么多张卡牌的价值最大是多少但是这样的话复杂度在  O(320*40^4),时间就超时了,实际上我们可以用使用了四种类型的卡牌数量来得到当前走到哪个位置,然后用下面四种状态分别转移然后就能得到答案

   

#include<bits/stdc++.h>
#define maxn 100005
#define mod 1000000007
using namespace std;
typedef long long ll;
ll dp[42][42][42][42];
ll n,m,a[500];
ll e[5],x;
int main(){
    cin>>n>>m;
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    for(int i=1;i<=m;i++){
        cin>>x;
        e[x]++;        
    }
    for(int A=0;A<=e[1];A++){
        for(int B=0;B<=e[2];B++){
            for(int C=0;C<=e[3];C++){
                for(int D=0;D<=e[4];D++){
                    ll v=a[A+2*B+3*C+4*D];
                    if(A)
                        dp[A][B][C][D]=max(dp[A][B][C][D],dp[A-1][B][C][D]+v);
                    if(B)
                        dp[A][B][C][D]=max(dp[A][B][C][D],dp[A][B-1][C][D]+v);
                    if(C)
                        dp[A][B][C][D]=max(dp[A][B][C][D],dp[A][B][C-1][D]+v);
                    if(D)    
                        dp[A][B][C][D]=max(dp[A][B][C][D],dp[A][B][C][D-1]+v);    
                }    
            }    
        }
    }
    cout<<dp[e[1]][e[2]][e[3]][e[4]]+a[0];
} 
原文地址:https://www.cnblogs.com/Lis-/p/11387711.html