앨리스와 밥이 게임을하고 있습니다. 카드 더미가 두 장 있습니다. 각 더미에는 N 개의 카드가 있으며 각 카드에는 점수가 있습니다. 그들은 번갈아 가며 카드 더미에서 맨 위 또는 맨 아래 카드를 가져 오며 카드의 점수가 그의 총점에 더해집니다. 앨리스와 밥은 둘 다 영리하며 가능한 한 많은 점수를 얻기 위해 카드를 집어 올 것입니다. 앨리스가 먼저 골라낸다면 얼마나 많은 점수를 얻을 수 있는지 아십니까?
입력
첫 번째 줄에는 케이스 수를 나타내는 정수 T (T≤100)가 포함됩니다.
각 케이스에는 3 줄이 있습니다. 첫 번째 줄은 N입니다 (N≤20). 두 번째 줄에는 N 개의 정수 ai (1≤ai≤10000)가 포함됩니다. 세 번째 줄에는 N 정수 bi (1≤bi≤10000)가 포함됩니다.
산출
각 경우에 대해 Alice가 얻을 수있는 가장 높은 점수를 나타내는 정수를 출력합니다.
샘플 입력
2 1 23 53 3 10 100 20 2 4 3
샘플 출력
(53) (105)
질문의 의미 : Alice와 Bob은 교대로 두 배열의 숫자를 가져옵니다. 매번 하나의 배열의 첫 번째 또는 마지막 숫자 만 가져올 수있을 때마다 Alice에게 최대 숫자 합계를 가져 오도록 요청합니다.
아이디어 : 첫 번째 어레이가 남아 있고 두 번째 어레이가 남아 있을 때 다음 단계를 수행하는 사람이 얻을 수있는 최대 값, 이전 단계에서 상대방의 최대 값 인 4 개의 전송 방법에서 전송할 수 있습니다. 배열의 첫 번째, 배열 1의 마지막, 배열 2의 첫 번째, 배열 2의 마지막.
for 루프는 작성하기가 정말 어렵거나 검색을 메모하기가 어렵습니다 8
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int N = 25;
int a[N], b[N], dp[N][N][N][N], n;
int dfs(int i, int j, int p, int q, int sum) {
if(i > j && p > q) return 0;
if(dp[i][j][p][q]) return dp[i][j][p][q];
if(i <= j) {
dp[i][j][p][q] = max(dp[i][j][p][q], sum - dfs(i + 1, j, p, q, sum - a[i]));
dp[i][j][p][q] = max(dp[i][j][p][q], sum - dfs(i, j - 1, p, q, sum - a[j]));
}
if(p <= q) {
dp[i][j][p][q] = max(dp[i][j][p][q], sum - dfs(i, j, p + 1, q, sum - b[p]));
dp[i][j][p][q] = max(dp[i][j][p][q], sum - dfs(i, j, p, q - 1, sum - b[q]));
}
return dp[i][j][p][q];
}
int main(){
// freopen("in.txt", "r", stdin);
int t;
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) {
scanf("%d", &b[i]);
sum += b[i];
}
memset(dp, 0, sizeof(dp));
printf("%d\n", dfs(1, n, 1, n, sum));
}
return 0;
}