题目链接:https://www.luogu.com.cn/problem/P1541
用f[i][j][k][l]表示1-4种爬行卡片依次用了i,j,k,l个,所能取得的最大值。因为当前位置在a[1+i+2*j+3*k+4*l],所以加上当前格的分数。有状态转移方程:
f[i][j][k][l]=max(f[i-1][j][k][l],f[i][j-1][k][l],f[i][j][k-1][l],f[i][j][k][l-1])+a[1+i+2*j+3*k+4*l];答案就是f[c[1]][c[2]][c[3]][c[4]],c[1]到c[4]分别表示每种爬行卡片的个数
代码如下:
#include<bits/stdc++.h> using namespace std; const int maxt=42; #define ll long long ll f[maxt][maxt][maxt][maxt]; int a[400],c[5]; int main(){ int i,j,k,l,n,m,t; memset(a,0,sizeof(a));memset(c,0,sizeof(c)); //freopen("luogu1541.txt","r",stdin); cin>>n>>m; for (i=1;i<=n;i++) cin>>a[i]; int x; for (i=1;i<=m;i++){ cin>>x;c[x]++; } memset(f,0,sizeof(f)); for (i=0;i<=c[1];i++) for (j=0;j<=c[2];j++) for (k=0;k<=c[3];k++) for (l=0;l<=c[4];l++){ if (i>0) f[i][j][k][l]=max(f[i][j][k][l],f[i-1][j][k][l]); if (j>0) f[i][j][k][l]=max(f[i][j][k][l],f[i][j-1][k][l]); if (k>0) f[i][j][k][l]=max(f[i][j][k][l],f[i][j][k-1][l]); if (l>0) f[i][j][k][l]=max(f[i][j][k][l],f[i][j][k][l-1]); f[i][j][k][l]+=a[1+i+2*j+3*k+4*l]; } //cout<<f[c[1]][c[2]][c[3]][c[4]]<<endl; fclose(stdin); return 0; }