N - Maximum Sum of Products(cf原题)题解
[题目传送门](Problem - 1519D - Codeforces (Unofficial mirror by Menci))
题目大意:给定两个长为 n 的序列 a 和 b。你可以对 a 的一段区间翻转,也可以不翻转,要求翻转后 a 与 b 对应位置之积的和最大。

我的题解就比较暴力了,直接跑循环求翻转后能改变的最大值 res ,如果 res 小于 0 则不用翻转,反之答案则为翻转前求和的值加上 res;
1 for(int k = 1; k <= n; k++) 2 { 3 sum = 0; 4 for(int i = k, j = k + 1; i > 0 && j <= n; i--, j++)// 此时翻转的个数为偶数,翻转区间从 k 和 k + 1 开始分别向两边扩散 5 { 6 sum += a[i] * b[j] + a[j] * b[i] - a[i] * b[i] - a[j] * b[j]; 7 res = max(res, sum); 8 } 9 sum = 0; 10 for(int i = k - 1, j = k + 1; i > 0 && j <= n; i--, j++)// 此时翻转的个数为奇数,翻转中心不改变所以翻转区间从 k - 1 和 k + 1 开始分别向两边扩散 11 { 12 sum += a[i] * b[j] + a[j] * b[i] - a[i] * b[i] - a[j] * b[j]; 13 res = max(res, sum); 14 } 15 }
这里的 k 值表示的是翻转区间的中值,这里分为两种情况;
1、翻转区间的数的个数为偶数时,计算翻转区间改变值从 k, k + 1 两边向外扩散;
2、翻转区间的数的个数为奇数时,计算翻转区间从 k - 1, k + 1 开始向两边扩散,因为如果翻转区间的个数为奇数,中间值是不会发生改变的。
举个栗子:
a:1 2 3 4 5 6
b: 6 5 4 3 2 1
转3 a:1 4 3 2 5 6
我们选取 a [ 3 ] (也就 3 )为中点,如果我翻转的个数为 3 ,我们会发现翻转之后中点是不会改变的。
下面是完整代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <vector> 5 #include <cmath> 6 #include <cstring> 7 #include <queue> 8 #include <map> 9 #include <unordered_map> 10 #include <set> 11 #define ll long long 12 #define ull unsigned long long 13 #define ci const int 14 #define PLL pair<ll, ll> 15 #define PII pair<int, int> 16 #define PSI pair<string, int> 17 #define MAX1 0x3f3f3f3f 18 #define lowbit(x) x &(-x) 19 using namespace std; 20 ci N = 5e4 + 7; 21 ll a[N], b[N]; 22 int main() 23 { 24 int n; 25 scanf("%d", &n); 26 ll ans = 0; 27 ll sum = 0; 28 ll res = 0; 29 for(int i = 1; i <= n; i++) 30 scanf("%d", a + i); 31 for(int i = 1; i <= n; i++) 32 { 33 scanf("%d", b + i); 34 ans += a[i] * b[i]; 35 } 36 for(int k = 1; k <= n; k++) 37 { 38 sum = 0; 39 for(int i = k, j = k + 1; i > 0 && j <= n; i--, j++) 40 { 41 sum += a[i] * b[j] + a[j] * b[i] - a[i] * b[i] - a[j] * b[j]; 42 res = max(res, sum); 43 } 44 sum = 0; 45 for(int i = k - 1, j = k + 1; i > 0 && j <= n; i--, j++) 46 { 47 sum += a[i] * b[j] + a[j] * b[i] - a[i] * b[i] - a[j] * b[j]; 48 res = max(res, sum); 49 } 50 } 51 ans += res; 52 printf("%lld", ans); 53 return 0; 54 }

浙公网安备 33010602011771号