3.30 CF
题意
两个数组a和b,ans=每一项相乘的乘积和,问连续的子集交换之后,ans最大是多少
题解
以一个数为轴交换左右算乘积和取最大值,或者两个数为轴交换左右算乘积和取最大值。
有一个优化(类似于马拉车,好妙
读入的时候每隔一个数多读一个空格,
这样只要考虑以一个数为轴交换左右算乘积和取最大值。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX = 1e4 + 10;
const int INF = 1e9 + 7;
ll sum[MAX];
ll a[MAX] = {0};
ll b[MAX] = {0};
int main() {
int n;
scanf("%d", &n);
for (int i = 1, j = 1; i <= n; i++, j += 2) {
scanf("%lld", &a[j]);
}
for (int i = 1, j = 1; i <= n; i++, j += 2) {
scanf("%lld", &b[j]);
}
ll ans = 0, tot = 0;
for (int i = 1; i <= 2 * n - 1; i++) {
sum[i] = a[i] * b[i];
tot += sum[i];
}
ans = tot;
int len = 2 * n - 1;
for (int i = 1; i <= len; i++) {
ll tmp = tot;
ll L = i - 1, R = i + 1;
while(1) {
if(L < 1 || R > len) break;
tmp = tmp - sum[L] - sum[R];
tmp = tmp + a[L] * b[R] + a[R] * b[L];
ans = max(ans, tmp);
L--, R++;
}
}
printf("%lld\n", ans);
}