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 }

 

posted @ 2022-07-05 15:19  aYi_7  阅读(150)  评论(2)    收藏  举报