Luogu 1541 乌龟棋

题目链接:https://www.luogu.org/problemnew/show/P1541

思路:

考虑若一张卡片被使用过,则可以从它当时的状态来进行转移。

故设$f[i][j][k][l]$表示用了$i$张$1$卡,$j$张$2$卡......时分数的最大值。

枚举四张卡片是否使用过,从中选取最大的,最后加上当前的得分。

启示:

$dp$不关心其过程是怎么实现的,即具体细节,只关心结果。

数组...开大些...

代码:

#include <bits/stdc++.h>
const int MAXN=4000;
const int MAXM=50;
using namespace std;
int n,m,b[MAXN],c[MAXN],num[10],f[MAXM][MAXM][MAXM][MAXM];
int main(){
    cin>>n>>m;
    for(int i=0;i<n;i++) cin>>b[i];
    for(int i=1;i<=m;i++){
        cin>>c[i];
        num[c[i]]++; 
    }
    for(int i=0;i<=num[1];i++){
        for(int j=0;j<=num[2];j++){
            for(int k=0;k<=num[3];k++){
                for(int l=0;l<=num[4];l++){
                    if(i)
                        f[i][j][k][l]=max(f[i][j][k][l],f[i-1][j][k][l]);
                    if(j)
                        f[i][j][k][l]=max(f[i][j][k][l],f[i][j-1][k][l]);
                    if(k)
                        f[i][j][k][l]=max(f[i][j][k][l],f[i][j][k-1][l]);
                    if(l) 
                        f[i][j][k][l]=max(f[i][j][k][l],f[i][j][k][l-1]);
                    f[i][j][k][l]+=b[i+j*2+k*3+l*4];
                }
            }
        }
    }
    cout<<f[num[1]][num[2]][num[3]][num[4]]<<endl;
    return 0;
}

 

posted @ 2019-07-08 19:41  BeyondLimits  阅读(143)  评论(0编辑  收藏  举报