http://codevs.cn/problem/1068/
我的思路是由len推导len+1层。
因为计算m个卡片最大值,需要知道m-1个卡片的最大值。(不知道网上其他人的算法是怎么理解的,感觉自己的算法很耗时间)
#include<iostream>
using namespace std;
int dp[41][41][41][41];
int a[351];
int n,m,t;
int mi=0,mj=0,mk=0,ml=0;
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
int mt=m;
while(mt--){
cin>>t;
if(t==1){
++mi;
}else if(t==2){
++mj;
}else if(t==3){
++mk;
}else if(t==4){
++ml;
}
}
for(int len=0;len<=m;len++){
// cout<<"-----------------------"<<endl;
// cout<<"len="<<len<<endl;
for(int i=0;i<=len&&i<=mi;i++){
for(int j=0;j+i<=len&&j<=mj;j++){
for(int k=0;i+j+k<=len&&k<=mk;k++){
int l=len-i-j-k;
if(l>ml)continue;
// cout<<i<<" ";cout<<j<<" ";cout<<k<<" ";cout<<l<<" ";
// cout<<dp[i][j][k][l]<<endl;
int num=i*1+j*2+k*3+l*4+1;
if(num+1<=n)dp[i+1][j][k][l]=max(dp[i+1][j][k][l],dp[i][j][k][l]+a[num+1]);
if(num+2<=n)dp[i][j+1][k][l]=max(dp[i][j+1][k][l],dp[i][j][k][l]+a[num+2]);
if(num+3<=n)dp[i][j][k+1][l]=max(dp[i][j][k+1][l],dp[i][j][k][l]+a[num+3]);
if(num+4<=n)dp[i][j][k][l+1]=max(dp[i][j][k][l+1],dp[i][j][k][l]+a[num+4]);
}
}
}
}
// for(int i=0;i<=mi;i++){
// for(int j=0;j<=mj;j++){
// for(int k=0;k<=mk;k++){
// for(int l=0;l<=ml;l++){
// cout<<
// }
// }
// }
// }
cout<<dp[mi][mj][mk][ml]+a[1]<<endl;
return 0;
}