L - Pokémon Army (easy version)题解
[题目传送门](Problem - 1420C1 - Codeforces (Unofficial mirror by Menci))
题目大意:给出一个数组 a, 去求 a(b1) - a(b2) + a(b3) + …… 的最大值
其中 b 为 a 数组的下标,b必须满足,b1 < b2 < b3 < ……;
看一下案例 3;
7 0 //这个题里面 p 值没什么用因为都是0
1 2 5 4 3 6 7
在这里答案选取的是 5 - 3 + 7 = 9, 其中 7 的下标大于 3 的下标,3 的下标大于 5 的下标
不可以是 5 - 1 + 4 - 2 + 7,因为这样就不满足题意了;
分析一下, 在 a 数组中,我们并不知道在最优解中某一个数是加还是减所以我们需要开两个动规数组,
我比较喜欢 f 和 g;
f [ i ] 表示在当前这个数相加的情况,g [ i ] 表示当前这个数相减的情况;
f [ i ] 和 g [ i ] 都表示 1 ~ i 和的最大值;f [ 0 ] 初始化为0;
1 for(int i = 1; i <= n; i++)//核心代码 2 { 3 f[i] = max(f[i - 1], g[i - 1] + a[i]); 4 g[i] = max(g[i - 1], f[i - 1] - a[i]); 5 }
因为在最优解中有的数并没有拿,所以我们需要去和前步的状态去对比一下,就有了代码中的
f [ i - 1 ] 和 g [ i - 1 ];
f [ i ] 表示判断是否相加上第 i 个数,所以在他的前一步的状态应该是相减所以是 g [ i - 1];
反正g[i]的前一步状态是f [ i - 1 ];
因为 f [ i ] 和 g [ i ] 是两种情况,所以最后的答案需要取 f [ i ] 和 g [ i ] 其中更大的一个。
下面是完整代码:
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 ll t, n, q; 21 int main() 22 { 23 scanf("%lld", &t); 24 while(t--) 25 { 26 scanf("%lld%lld", &n, &q); 27 ll ans; 28 vector<ll>a(n + 1); 29 vector<ll>f(n + 1, -1); 30 vector<ll>g(n + 1); 31 for(int i = 1; i <= n; i++) 32 scanf("%lld", &a[i]); 33 for(int i = 1; i <= n; i++) 34 { 35 f[i] = max(f[i - 1], g[i - 1] + a[i]); 36 g[i] = max(g[i - 1], f[i - 1] - a[i]); 37 } 38 ans = max(f[n], g[n]); 39 printf("%lld\n", ans); 40 } 41 return 0; 42 }

浙公网安备 33010602011771号