题意

有一个一维的地图,地图上有很多个格子,每个格子上都标了一个值,现在有一个乌龟在起点处,位置为1,现在给你4种卡牌,分别标有1,2,3,4,使用卡牌可以让乌龟走卡牌上的数,即使用1让乌龟走一格,使用2让乌龟走两个,现在给你一些这种卡牌,保证卡牌用完能够走到终点,要求你如何使用能让乌龟所有停留的点上的值加起来最大。

解析

这个题目很简单,看懂了题目之后就是一个简单的dp,直接暴力的递推,然后维护格子的最大值就好了,

设一个dp数组为分别表示每一种卡牌使用了多少个,然后递推到最后,即所有卡牌都用完,

也就是走到最后的情况就是最大的值了,直接暴力向后推就可以了,将当前的格子值加上向后分别走1,2,3,4最大的累加即可。

代码再加一点注释应该就没有什么问题了

代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN=125;
int dp[MAXN][MAXN][MAXN][MAXN];
int mp[405],n,m,cnt[5];

int dfs(int p,int a,int b,int c,int d){
    if(dp[a][b][c][d]) return dp[a][b][c][d];          //如果这个点来过了就不用再推了
    int res=0;                             //分别计算abcd各用一张然后累加
    if(a<cnt[1]) res=max(res,dfs(p+1,a+1,b,c,d));      
    if(b<cnt[2]) res=max(res,dfs(p+2,a,b+1,c,d));
    if(c<cnt[3]) res=max(res,dfs(p+3,a,b,c+1,d));
    if(d<cnt[4]) res=max(res,dfs(p+4,a,b,c,d+1));
    return dp[a][b][c][d] = res + mp[p];   
}

int main(void){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i)
        scanf("%d",&mp[i]);   //读入每一个格子的值。
    for(int i=1;i<=m;++i){     //统计每种牌的数量
        int k;
        scanf("%d",&k);
        cnt[k]++;
    }
    printf("%d",dfs(1,0,0,0,0));      //从0000开始递推到abcd即四张牌都全部用完,p的初始值为1
    return 0;                         //表示原点为1
}