Classic.. just classic. It is a mix of Greedy and DP. The naive DP is, iterate over all [1..Bi] which is O(n^3). However, deeper thought into the problem indicates: we only need to consider [1, Bi]. So then it becomes O(n)!
Lesson learnt: DP choices can be optimized!
#include <cmath> #include <cstdio> #include <vector> #include <string> #include <iostream> #include <algorithm> #include <bitset> using namespace std; #define MAX_V 101 typedef long long LL; LL calc(vector<LL> &in) { size_t len = in.size(); vector<vector<LL>> dp(len, vector<LL>(2, 0)); for (int i = 1; i < len; i++) { dp[i][0] = std::max(dp[i][0], in[i - 1] - 1 + dp[i-1][1]); dp[i][1] = std::max(dp[i][1], in[i] - 1 + dp[i - 1][0]); dp[i][1] = std::max(dp[i][1], abs(in[i - 1] - in[i]) + dp[i - 1][1]); } return std::max(dp[len - 1][0], dp[len - 1][1]); } int main() { int t; cin >> t; while (t--) { int n; cin >> n; vector<LL> in(n); for (int i = 0; i < n; i++) cin >> in[i]; LL ret = calc(in); cout << ret << endl; } return 0; }