Simple DP.
DP [I] [J]: in the position I, the status of decline is J, and the maximum profit is obtained.
Enumeration status. If the number X to be added is greater than the minimum number X, the status changes to X.
If X is smaller than the smallest, the status is J + X.
If X is equal to the smallest value, it is incremented sequentially until the smallest value is greater than X.
# Include <iostream> # include <stdio. h> # include <vector> # include <queue> # include <stack> # include <string. h> # include <algorithm> # include <math. h> using namespace STD; int Pan (int x) {If (x = 2) return 1; if (x = 4) return 2; If (x = 8) return 3; if (x = 16) return 4;} int DP [505] [1 <13]; int A [550]; queue <int> que; void Chu (int s, int SS, int K, int X) {DP [s] [x] = max (DP [s] [X], DP [ss] [0] + x); If (k = 0) return; If (DP [ss] [k] = 0) return; d P [s] [k] = max (DP [s] [K], DP [ss] [k]); While (! Que. empty () que. pop (); int y = x; int add = x; For (INT I = 0; I <13; I ++) {int now = (1 <I ); if (K & now) = 0) continue; If (now <Y) DP [s] [x] = max (DP [s] [X], DP [ss] [k] + x); If (now> Y) DP [s] [K + x] = max (DP [s] [K + x], DP [ss] [k] + Add); If (now! = Y) return; y = y * 2; add + = y;} DP [s] [Y] = max (DP [s] [Y], DP [ss] [k] + Add);} int main () {int t, n; scanf ("% d", & T); While (t --) {scanf ("% d", & N); int sum = 0; For (INT I = 1; I <= N; I ++) {scanf ("% d", & A [I]); sum + = A [I];} For (INT I = 1; I <= N; I ++) {for (Int J = 0; j <= sum; j ++) DP [I] [J] = 0;} For (INT I = 1; I <= N; I ++) {for (Int J = 0; j <= sum; j ++) {Chu (I, I-1, J, a [I]);} int Maxx = 0; For (INT I = 0; I <= sum; I ++) Maxx = max (Maxx, DP [N] [I]); cout <Maxx <Endl;} return 0 ;}
Zoj-3802-Easy 2048 again