Hdu 4960 Another OCD Patient (memory)
Link: hdu 4960 Another OCD Patient
Given a sequence with a length of n, and then giving n numbers of ai, it indicates the cost of merging I numbers. Each time, a continuous subsequence can be converted into a number, that is, the sum of each item in the sequence. It is required that a sequence with a given length of n be converted into a return string, and a number can only be merged once.
Solution: dp [l] [r] indicates the minimum cost from l to r to the input string. dp [l] [r] = min (val (r? L + 1), val (r? I + 1) + val (j? L + 1) + dp [j + 1] [I? 1]), when I decreases by 1, the corresponding j must increase, which can reduce the majority of enumeration.
#include
#include
#include using namespace std;typedef long long ll;const int maxn = 5005;int N, arr[maxn], dp[maxn][maxn];ll x, val[maxn];inline ll getval (int l, int r) { return val[r] - val[l-1];}void init () { memset(dp, -1, sizeof(dp)); val[0] = 0; for (int i = 1; i <= N; i++) { scanf("%I64d", &x); val[i] = val[i-1] + x; } for (int i = 1; i <= N; i++) scanf("%d", &arr[i]);}int solve (int l, int r) { if (l > r) return 0; if (dp[l][r] != -1) return dp[l][r]; int& ret = dp[l][r]; ret = arr[r-l+1]; int mv = l; for (int i = r; i > l; i--) { ll u = getval(i, r); while (getval(l, mv) < u && mv < i) mv++; if (mv >= i) break; if (getval(l, mv) == u) ret = min(ret, arr[r-i+1] + arr[mv-l+1] + solve(mv+1, i-1)); } return ret;}int main () { while (scanf("%d", &N) == 1 && N) { init(); printf("%d\n", solve(1, N)); } return 0;}