k个最大的m段子数组和
来源:互联网 发布:网络电视看不见翡翠台 编辑:程序博客网 时间:2024/05/19 14:17
从数组中选择k组长度为m的子数组,要求其和最大
问题描述:
给定长度为n的数组a[],从中选择k个长度为m的子数组,要求和最大。
形式描述为:选择
问题分析:
【思路1】先从简单粗暴的方法入手,怎么办?寻找所有的k个长度为m的子数组,然后选择其中和最小的。第一个长度为m的子数组开始位置可能为0...(k-1)*m,然后第二个子数组的下标?第三个子数组下标?太复杂了而且时间复杂度肯定超高,不能忍,换个方法吧。
【思路2】再看一下问题,要求和最大,求最值问题十有八九都是DP问题,试试吧。DP题目子问题怎么定义是关键,然后这东西基本只能靠经验了(嗯,算法导论上就是这么说的)。从后往前考虑,那么对于最后一个元素,只有两种情况,被选中到子数组中或者没有被选到子数组中。如果被选中,那么首先计算最后m个元素的和,剩下的问题就化为从前面长度为n-m的数组中选择k-1组和最大的子数组。如果没选中最后一个,也好办,直接转化为从前面n-1个元素中选择k组和最大的子数组。分析后我们有:
子问题定义: dp[i][j] = 从前i个元素中选择j个子数组的最大和
状态转移方程: dp[i][j] = max(dp[i-1][j], dp[i-m][j-1] + sum(a[i-m]...a[i-1]))
初始条件: dp[0][j] = 0; dp[i][0] = 0; if (i < j * m) dp[i][j] = 0;
AC代码如下:
1 #include <iostream> 2 #include <string> 3 #include <vector> 4 #include <algorithm> 5 #include <functional> 6 #include <numeric> 7 using namespace std; 8 9 int main()10 {11 int n, m, k;12 cin >> n >> m >> k;13 14 vector<int> v(n, 0);15 for (int i = 0; i < n; ++i)16 {17 cin >> v[i];18 }19 20 // dp[i][j] = choose j pairs integers from the first i elements21 // Then base on the ith is chosen or not, there are two case:22 // not choose ith element, the dp[i][j] = dp[i-1][j]23 // choose ith element, the dp[i][j] = dp[i-m][j-1] + sum(a[i-1]...a[i-m])24 // so dp[i][j] = max(dp[i-1][j], dp[i-m][j-1] + sum(a[i-1]...a[i-m])25 // base case: assert (i >= j * m) if not 0 dp[i][j] = 026 // the problem is equal to find dp[n][k]27 28 vector<vector<long long> > dp(n+1, vector<long long>(k+1, 0));29 30 // base case31 for (int i = 0; i < n + 1; ++i)32 {33 for (int j = 0; j < k + 1; ++j)34 {35 if (i < j * m)36 {37 dp[i][j] = 0;38 }39 }40 }41 42 // bottom to up43 for (int i = 1; i < n + 1; ++i)44 {45 for (int j = 1; j < k + 1; ++j)46 {47 if (i >= j * m)48 {49 long long lastPairSum = accumulate(v.begin() + i - m, v.begin() + i, 0LL);50 dp[i][j] = max(dp[i-1][j], dp[i-m][j-1] + lastPairSum); 51 }52 53 }54 }55 56 long long ans = dp[n][k];57 cout << ans << endl;58 return 0;59 }
0 0
- k个最大的m段子数组和
- hdu1024 最大M段子段和
- hdu1024(m段子段和最大)
- 【算法】寻找K个最大的数组
- hdu1024 Max Sum Plus Plus(M段子序列的最大和)
- 简单dp之——m段子序列的最大和
- hdu Max Sum Plus Plus(最大m段子段和)
- hdu Max Sum Plus Plus(最大m段子段和)
- (5)最大m段子序列和问题____动态规划
- HDOJ1024(m段子序列最大和模板题)
- HDOJ 1024 Max Sum Plus Plus 最大K段子序列和(01背包 + 滑动数组 + 优化)
- 最大m个字段和+两个滚动数组(1024)
- 最大段子和
- 计算m个数组的和
- 求数组中最大K个值的下标
- N个降序数组,找到最大的K个数
- 打印N个数组整体最大的Top K
- 寻找数组的第k个最大者
- [STL] map
- 解决NAT模式,主机ping不通虚拟机
- springMVC+mybatis框架搭建
- CodeVS2599 电路的稳定性
- STL学习之map
- k个最大的m段子数组和
- Tomcat默认访问路径的配置
- Iterator抽取迭代基类/Memento抽取备忘管理类/Interpreter终结非终结解释
- 线程之间的通信
- [bzoj1093][ZJOI2007]最大半连通子图
- html5应用缓存
- list的独有sort
- 欢迎使用CSDN-markdown编辑器
- Linux战地日记——ls命令、注释、管道线和后台命令