题目
典型的DP
AC代码
#include <cstdio>
#include <iostream>
using namespace std;
int dp[45][45][45][45],n,m,a,b,c,d,cnt,arr[355]; //dp数组如上,arr数组记录每个点的分数,a,b,c,d分别记录4种卡牌的个数
int main() {
cin>>n>>m;
for(int i=1;i<=n;i++)scanf("%d",&arr[i]);
for(int i=1;i<=m;i++){
int x;
scanf("%d",&x);
if(x==1)a++;
if(x==2)b++;
if(x==3)c++;
if(x==4)d++;
}
dp[1][1][1][1]=arr[1]; //初始化
for(int i=1;i<=a+1;i++){ //循环进行动规核心
for(int j=1;j<=b+1;j++){
for(int k=1;k<=c+1;k++){
for(int l=1;l<=d+1;l++){
cnt=i+j*2+k*3+l*4-9; //边界处理(从1开始的我调了好久......)
dp[i][j][k][l]=max(dp[i][j][k][l],dp[i-1][j][k][l]+arr[cnt]);
dp[i][j][k][l]=max(dp[i][j][k][l],dp[i][j-1][k][l]+arr[cnt]);
dp[i][j][k][l]=max(dp[i][j][k][l],dp[i][j][k-1][l]+arr[cnt]);
dp[i][j][k][l]=max(dp[i][j][k][l],dp[i][j][k][l-1]+arr[cnt]); //状态转移方程
}
}
}
}
cout<<dp[a+1][b+1][c+1][d+1]<<endl; //输出
return 0;
}
ヾ( ̄▽ ̄)ByeBye