第一感觉是定义状态f[n][i][j][k][kk],但这样空间和时间都承受不下。我们可以设状态为f[i][j][k][kk],这样可以省掉一个n,因为我们依据行走步数可以直接算出行走距离.
Code:
#include<cstdio> #include<algorithm> using namespace std; const int maxn = 42; long long f[maxn][maxn][maxn][maxn]; int val[400], steps[10]; inline int dist(int a,int b,int c,int d) { return a + 2*b + 3*c + 4*d; } int main() { // freopen("in.txt","r",stdin); int n,m; scanf("%d%d",&n,&m); for(int i = 0;i < n;++i)scanf("%d",&val[i]); for(int i = 1;i <= m;++i) { int a; scanf("%d",&a); ++ steps[a]; } f[0][0][0][0] = val[0]; for(int i = 0;i <= steps[1]; ++i) for(int j = 0;j <= steps[2];++j) for(int k = 0;k <= steps[3]; ++k) for(int kk = 0; kk <= steps[4]; ++kk) { if(i + j + k + kk == 0) continue; int h = dist(i,j,k,kk); if(i >= 1)f[i][j][k][kk] = max(f[i][j][k][kk], f[i-1][j][k][kk] + val[h]); if(j >= 1)f[i][j][k][kk] = max(f[i][j][k][kk], f[i][j-1][k][kk] + val[h]); if(k >= 1)f[i][j][k][kk] = max(f[i][j][k][kk], f[i][j][k-1][kk] + val[h]); if(kk >= 1)f[i][j][k][kk] = max(f[i][j][k][kk], f[i][j][k][kk-1] + val[h]); } printf("%lld",f[steps[1]][steps[2]][steps[3]][steps[4]]); return 0; }