传送门
解题思路
一道裸的dp。
用dp[i][j][k][kk]表示用i个1步,j个2步,k个3步,kk个4步所获得的最大价值,然后状态转移方程就要分情况讨论了(详见代码)
然后就是一开始统计一下几步的卡片共有几张存在num里。
这道题的范围小,所以可以大胆的用思维数组QAQ!!!
AC代码
1 #include<iostream> 2 using namespace std; 3 const int maxn=355; 4 int n,m,a[maxn],num[5]; 5 int dp[45][45][45][45]; 6 int main() 7 { 8 cin>>n>>m; 9 for(int i=0;i<=n-1;i++){ 10 cin>>a[i]; 11 } 12 for(int i=1;i<=m;i++){ 13 int x; 14 cin>>x; 15 num[x]++; 16 } 17 for(int i=0;i<=num[1];i++){ 18 for(int j=0;j<=num[2];j++){ 19 for(int k=0;k<=num[3];k++){ 20 for(int kk=0;kk<=num[4];kk++){ 21 int now=1*i+2*j+3*k+4*kk; 22 if(i!=0) dp[i][j][k][kk]=max(dp[i][j][k][kk],dp[i-1][j][k][kk]+a[now]); 23 if(j!=0) dp[i][j][k][kk]=max(dp[i][j][k][kk],dp[i][j-1][k][kk]+a[now]); 24 if(k!=0) dp[i][j][k][kk]=max(dp[i][j][k][kk],dp[i][j][k-1][kk]+a[now]); 25 if(kk!=0) dp[i][j][k][kk]=max(dp[i][j][k][kk],dp[i][j][k][kk-1]+a[now]); 26 } 27 } 28 } 29 } 30 cout<<dp[num[1]][num[2]][num[3]][num[4]]+a[0]; 31 return 0; 32 }
//NOIP2010提高组 t2