题目链接: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; }