子序列
子序列
给定一个长度为 的整数序列 。
请你找到一个该序列的子序列,要求:
- 该子序列的所有元素之和必须是奇数。
- 在满足条件 的前提下,该子序列的所有元素之和应尽可能大。
输出你找到的满足条件的子序列的所有元素之和。
保证至少存在一个满足条件的子序列。
注意,子序列不一定连续。
输入格式
第一行包含一个整数 。
第二行包含 个整数 。
输出格式
输出一个整数,表示满足条件的子序列的所有元素之和。
数据范围
前 个测试点满足 。
所有测试点满足 ,。
输入样例1:
4 -2 2 -3 1
输出样例1:
3
输入样例2:
3 2 -5 -3
输出样例2:
-1
解题思路
把所有的正数相加,然后分类讨论:
- 所有的正数的和为奇数,那么这个就是最大值。
- 所有的正数的和为偶数:
- 负偶数一定不选,因为一个数加上偶数不影响奇偶性,而且加上负偶数总和会变小。
- 正偶数一定选,同理因为一个数加上偶数不影响奇偶性,而且加上正偶数总和会变大。
- 负奇数最多选一个,如果多于一个,我们总是可以选出两个负奇数,这两个负奇数的和就变成负偶数了,加上后不影响奇偶性且总和变小。
- 正奇数最多只能有一个不选,如多于一个不选,那么总是可以选出两个正奇数,这两个正奇数的和是正偶数,加上后不影响奇偶性且总和会变大。
因此贪心的思路是,先把所有的正数加起来,如果得到的总和是奇数,那么就是答案;如果是偶数,那么就需要加上一个负奇数或者减去一个正奇数,答案就是这两种情况的一个最大值。
AC代码如下:
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 5 int main() { 6 int n, a = -2e9, b = 2e9, sum = 0; 7 scanf("%d", &n); 8 while (n--) { 9 int val; 10 scanf("%d", &val); 11 if (val > 0) sum += val; 12 if (val < 0 && val % 2) a = max(a, val); 13 else if (val > 0 && val % 2) b = min(b, val); 14 } 15 16 printf("%d", sum % 2 ? sum : max(sum + a, sum - b)); 17 18 return 0; 19 }
这题还可以用动态规划来做,因为可以发现这是一个背包(组合)的问题。
设集合表示从前个数中选,且选的数的总和模后为的所有方案的集合。。
状态转移方程为。
AC代码如下:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 const int N = 1e5 + 10; 7 8 int a[N], f[N][2]; 9 10 int main() { 11 int n; 12 scanf("%d", &n); 13 for (int i = 1; i <= n; i++) { 14 scanf("%d", a + i); 15 } 16 17 memset(f, -0x3f, sizeof(f)); 18 f[0][0] = 0; 19 for (int i = 1; i <= n; i++) { 20 for (int j = 0; j <= 1; j++) { 21 f[i][j] = max(f[i - 1][j], f[i - 1][((j - a[i]) % 2 + 2) % 2] + a[i]); 22 } 23 } 24 25 printf("%d", f[n][1]); 26 27 return 0; 28 }
参考资料
AcWing 4414. 子序列(AcWing杯 - 周赛):https://www.acwing.com/video/3846/
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/16248327.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效