传送门题目:https://www.luogu.org/problem/show?pid=1541
其实这道题想到了就很简单,但很难想到用思维的dp,这非常少见。
看到每张牌不超过40张,这数据范围就是给你开思维dp的
自然想到用dp[ i ][ j ][ k ][ l ]表示用了i张1,j张2,k张3 , l 张4的最大值
用i张1,j张2,k张3 , l 张4自然跳到了 第(1+i+2*j+3*k+4*l)格,枚举四种情况,再加上第(1+i+2*j+3*k+4*l)格的值就行了
//Gang #include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<cstdlib> #include<cmath> #define FOR(x,y,z) for(int x=y;x<=z;x++) #define REP(x,y,z) for(int x=y;x>=z;x--) #define ll long long ],dp[][][][]; int n,m; ]; int x; using namespace std; int main() { scanf("%d %d",&n,&m); FOR(i,,n) scanf("%d",&score[i]); FOR(j,,m) { scanf("%d",&x); t[x]++; } FOR(i,,t[]) { FOR(j,,t[]) { FOR(k,,t[]) { FOR(l,,t[]) { )dp[i][j][k][l]=max(dp[i][j][k][l],dp[i-][j][k][l]); )dp[i][j][k][l]=max(dp[i][j][k][l],dp[i][j-][k][l]); )dp[i][j][k][l]=max(dp[i][j][k][l],dp[i][j][k-][l]); )dp[i][j][k][l]=max(dp[i][j][k][l],dp[i][j][k][l-]); dp[i][j][k][l]+=score[i+j*+k*+l*+]; } } } } printf(]][t[]][t[]][t[]]); ; }