动态规划
一道很正的动态规划题,直接进行分析:
原问题:选取所有卡片到最后一个格子是能够得到的最大分数;
子问题:四种卡片分别选i,j,k,l张时能得到的最大分数;
记dp[i][j][k][l]为四种卡片分别选出了i,j,k,l张时能够取得的最大分数。
有的人可能会按“前i个格子如何选取卡片”类似这样的套路分析,这里要注意的是,当每种卡片的个数确定了以后,走到的格子也是确定的,同时题目还确保了使用所有的卡片可以恰好到达最后一个格子,这就更没有必要讨论“前几个格子了”。
代码:
#include <iostream> #include <queue> #include <set> #include <map> #include <vector> #include <stack> #include <cmath> #include <algorithm> #include <cstdio> #include <cctype> #include <functional> #include <string> #include <cstring> #include <sstream> #include <deque> #define fir first #define sec second using namespace std; typedef long long ll; typedef pair<int,int> P; typedef pair<P,int> Q; const int inf1=2e9+9; const ll inf2=8e18+9; const ll mol=1e9+7; const int maxn=1e6+9; const ll maxx=1e12+9; int n,m,a[555],b[5]; int dp[55][55][55][55]; int main() { scanf("%d%d",&n,&m); for(int i=0;i<n;i++) scanf("%d",&a[i]); for(int i=0;i<m;i++) { int num; scanf("%d",&num); b[num]++; } dp[0][0][0][0]=a[0]; for(int i=0;i<=b[1];i++) for(int j=0;j<=b[2];j++) for(int k=0;k<=b[3];k++) for(int l=0;l<=b[4];l++) { if(i) dp[i][j][k][l]=max(dp[i][j][k][l],dp[i-1][j][k][l]+a[i+2*j+3*k+4*l]); if(j) dp[i][j][k][l]=max(dp[i][j][k][l],dp[i][j-1][k][l]+a[i+2*j+3*k+4*l]); if(k) dp[i][j][k][l]=max(dp[i][j][k][l],dp[i][j][k-1][l]+a[i+2*j+3*k+4*l]); if(l) dp[i][j][k][l]=max(dp[i][j][k][l],dp[i][j][k][l-1]+a[i+2*j+3*k+4*l]); } printf("%d\n",dp[b[1]][b[2]][b[3]][b[4]]); }