数组分割问题解法上总体来说就是用动态规划的方法求出2n个数中,取出n个数相加所能得到的所有的值,然后从中找到最接近sum/2的那个值。解法一中,每一步都需要更新每一个Heap中的每一个元素,而Heap中的元素个数随着K的增大而增大;解法二不再遍历Heap中的元素,而是遍历1---sum/2之间的值。解法二用了一个二维数组isOK来保存结果,isOK[i][j]表示能否找到i个数,使得他们的和等于j。下面是用解法二实现的源代码,如果要获得数组分割的具体分法,仍然可以用建立对象来保存索引的方法。
/*This is program will the sum of n elements which is close to the half the sum of 2*n elemens
input: an array having 2*n elements
output: the sum close to the half the sum of 2*n elements
*/
#include <stdio.h>
#include <stdlib.h>
void main()
{
int a[] = {1,5,7,8,9,6,3,11,20,17};
int n = sizeof(a)/sizeof(int)/2;
int sum = 0;
int i,j,k,v;
for(i=0;i<2*n;i++)
sum += a[i];
int **isOK = malloc(sizeof(int *)*(n+1));
for(i=0;i<n+1;i++){
isOK[i] = malloc(sizeof(int)*(sum/2+1));
}
for(i=0;i<(n+1);i++)
for(j=0;j<(sum/2+1);j++)
isOK[i][j] = 0;
isOK[0][0] = 1;
for(k=1;k<=2*n;k++){
int updateIndex = min(k,n);
for(j=updateIndex;j>=1;j--){
for(v=1;v<=sum/2;v++){
if(a[k-1]<=v && isOK[j-1][v-a[k-1]])
isOK[j][v] = 1;
}
}
}
for(i=sum/2;i>=0;i--){
if(isOK[n][i]==1){
printf("%d\n",i);
break;
}
}
}
int min(int x, int y)
{
return x<y?x:y;
}
分享到:
相关推荐
《编程之美》2.18节的解法二指出,从2n个数中选n个,可以考虑元素和大于、小于或等于总和的一半(Sum/2)的情况。由于大于Sum/2与小于等于Sum/2没有本质区别,因此只需要关注小于等于Sum/2的情况。 接下来,采用...
总之,最大子数组问题的分治解法展示了如何通过分解问题、独立解决子问题,然后合并结果来找到最优解。这种策略在处理复杂问题时非常有效,尤其是当问题的规模可以通过分割而显著减小时。在实际编程中,理解和掌握...
leetcode04_寻找两个正序数组的中位数解法.rar !!!CSDN的一个特性: 即使我设置成免费下载,被下载的次数多了之后也会变成付C币下载的了,这个很头疼. !!!因此如果没有C币但想要下载的朋友可以在b站视频下留言给我,留下...
并行化算法可以将原数组分割成多个子数组,在不同的处理器上同时进行处理,从而显著减少解决问题所需的时间。 ### 二、动态规划求解法 #### 2.1 动态规划的基本概念 - **定义**: 动态规划是一种算法策略,用于...
在这种方法中,我们使用一个二维数组`dp`来存储子问题的解。`dp[i][j]`表示前`i`个物品中选取若干个,其总重量不超过`j`的最大价值。我们通过递归地计算所有可能的子问题来填充这个数组。为了避免重复计算,我们会...
数组分段和最大值最小问题,也称为最小 m 段和问题,是一类经典的计算机算法问题,旨在找到一种分割方式,使得将给定的整数序列分割成 m 个连续子序列时,这些子序列和的最大值尽可能小。这个问题在实际应用中有着...
解题思路解法 1首先可以做个边界条件判断,数组的和 sum 如果是奇数直接返回 false把数组分割成两个子集,且每个子集的元素和相等,其实就相当于能否在数组中
我们可以定义一个二维数组dp[i][j],表示在前i个物品中选取总重量不超过j的情况下,能够得到的最大价值。状态转移方程为: ```markdown dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i]) ``` 其中,i表示第i个...
这个问题是LeetCode中的第659题,名为“分割数组为连续子序列”。题目要求给定一个升序排列的整数数组,判断是否可以将其分割成至少包含三个连续整数的子序列。如果可以,返回true;否则,返回false。题目中提到的...
### 双回文子串的相关解法 #### 一、双回文子串与后缀...需要注意的是,虽然Manacher算法在这种类型的问题中有着更高的效率和简洁性,但对于学习和理解后缀数组等高级数据结构来说,上述方法不失为一种好的实践方式。
部分背包问题允许物品被部分选取,即每个物品可以分割成任意大小。这种问题的解决通常需要更复杂的动态规划状态设计,比如dp[i][j]表示前i个物品中选取一部分,使得总重量不超过j时的最大价值。 P05: 动态规划优化 ...
在数学建模中,背包问题通常表现为一个二维数组,其中每个元素代表一个物品,包含两个属性:价值和重量。问题的目标是在不超过背包总容量的前提下,选择物品以最大化总价值。 **一、背包问题类型** 1. **0-1背包...
- **解法**: 使用一维或二维数组存储中间结果,避免重复计算。 2. **1013 Great Equipment** - **背景**: 在游戏中选择最佳装备组合。 - **解法**: 采用动态规划思想,通过状态转移方程求解最优值。 3. **1024...
2. **动态规划解法**:背包问题通常使用动态规划来求解。动态规划的思路是构建一个二维数组dp[i][j],其中dp[i][j]表示从前i个物品中选择,放入容量为j的背包中所能获得的最大价值。通过递推关系式来填充这个数组,...
对于01背包问题,我们可以定义一个二维数组dp[i][j],表示在前i个物品中选取总重量不超过j的物品所能获得的最大价值。状态转移方程如下: ``` dp[i][j] = max(dp[i-1][j], dp[i-1][j-wi] + vi) ``` 这里的dp[i-...
背包问题的典型解法是动态规划,通过构建二维数组dp[i][j]表示前i个物品放入容量为j的背包可以获得的最大价值。基本思路是将原问题分解为子问题,通过子问题的解来求解原问题。 三、动态规划状态转移方程 1. 0-1...
01背包问题的典型算法是动态规划,用一个二维数组dp[i][j]表示前i个物品放入容量为j的背包能得到的最大价值。状态转移方程为: ``` dp[i][j] = max(dp[i-1][j], dp[i-1][j-wi] + vi) (如果 j >= wi) dp[i][j] = dp...
0-1背包问题的特点是每种物品只能选择放入背包或者不放入,不能分割。 **一、0-1背包问题的基本概念** 在0-1背包问题中,我们有n个物品,每个物品i有重量wi和价值vi。有一个容量为W的背包,我们需要决定哪些物品...
动态规划是一种更有效的解法,通过构建二维数组,记录在前i个物品中选取总重量不超过j的物品所能达到的最大价值。状态转移方程为DP[i][j] = max(DP[i-1][j], DP[i-1][j-w[i]] + v[i]),其中DP[i][j]表示在前i个物品...
我们可以创建一个二维数组`dp[i][w]`表示前i个物品中选取总重量不超过w的最大价值,通过状态转移方程递推得到答案。 2. **完全背包问题**:每个物品可以无限次地选取。此时需要修改状态转移方程,考虑每个物品选取...