The meaning of problems: on paper you want a length of n * m bracketed sequence, the i-th position takes Videos left parenthesis is a [i% n], right parenthesis is spent Videos b [i% n], Q the minimum cost parentheses unfinished sequence. n <= 20, m <= 1e7
Ideas: If n and m restrictions regardless of the question to do well, provided DP [i] [j] is to position i, j is the balance factor cost, dp [i] [j] = min (dp [i - 1] [j - 1] + a [i], dp [i - 1] [j + 1] + b [i]), but this level of n * m to 2e8, which we can not afford. However, we can find a nature: the size of the balance factor of no more than 2 * n, because if more than 2 * n, we can not change an answer by exchanging the order, so the balance factor is less than 2 * n. We think about the transfer dp, we have found may be one matrix multiplication is performed once transferred (disposed transition matrix is C), then C [j] [j + 1] = a [i], C [j] [j - 1 ] = b [i], then by once this matrix to perform a transfer, because a and b are arrays of length n cycle, then we can again handle the n-th matrix transfer (seen from the associative matrix multiplication) and then fast matrix power to perform such a shift n times m times, we get a final answer.
Code:
#include <bits/stdc++.h> #define INF 2e9 #define LL long long using namespace std; int a[30], b[30], N; struct Matrix { LL a[55][55]; Matrix(int x = INF) { memset(a, 0x3f, sizeof(a)); for (int i = 0; i < N; i++) a[i][i] = x; } friend Matrix operator * (const Matrix& A, const Matrix& B) { Matrix ans; for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) for (int k = 0; k < N; k++) ans[i][j] = min(ans[i][j], A[i][k] + B[k][j]); return ans; } Matrix operator ^ (int y) { Matrix x = *this, ans(0); for (; y; y >>= 1) { if(y & 1) ans = ans * x; x = x * x; } return ans; } LL*operator [](int x) { return a[x]; } const LL*operator [](int x) const { return a[x]; } }; int main() { int n, m; scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); for (int i = 1; i <= n; i++) scanf("%d", &b[i]); N = 2 * n + 1; Matrix dp, A(0); dp[0][0] = 0; for (int i = 1; i <= n; i++) { Matrix tmp; for (int j = 0; j <= N; j++) { if(j) tmp[j - 1][j] = a[i]; if(j < 2 * n) tmp[j + 1][j] = b[i]; } A = A * tmp; } dp = dp * (A ^ m); printf("%lld\n", dp[0][0]); }