《编程之美》——数组分割

问题:
将一个无序、元素个数为2N的正整数数组分割为元素个数为N的两个数组,并使两个子数组的和最接近。

分析与解法:
【解法一】
动态规划的0-1背包问题。将heap[M](M表示从2N中所有可能的M个元素和组成的集合),从下到上(m->1…->N)最终求的完整的heap[N]。要点:可以想成求不大于sum/2的最接近集合,以下为分析:

假设数组A[1..2N]所有元素的和是SUM。模仿动态规划解0-1背包问题的策略,令S(k, i)表示前k个元素中任意i个元素的和的集合。显然:
S(k, 1) = {A[i] | 1<= i <= k}
S(k, k) = {A[1]+A[2]+…+A[k]}
S(k, i) = S(k-1, i) U {A[k] + x | x属于S(k-1, i-1) }
按照这个递推公式来计算,最后找出集合S(2N, N)中与SUM/2最接近的那个和。

代码:

#include<iostream>  
using namespace std;  

//有一个没有排序,元素个数为2N的正整数数组。要求把它分割为元素个数为N的两个数组,并使两个子数组的和最接近。  
int arr[] = {
  0,1,5,7,8,9,6,3,11,20,17};  
const int N=5;  
const int SUM = 87;  

// 模仿动态规划解0-1背包问题的策略  
int solve1()  
{  
    int i , j , s;  
    int dp[2*N+1][N+1][SUM/2+2];  

    /* 
    用dp(i,j,c)来表示从前i个元素中取j个、且这j个元素之和不超过c的最佳(大)方案,在这里i>=j,c<=S 
    状态转移方程:    
    限第i个物品       不取   
    dp(i,j,c)=max{dp(i-1,j-1,c-a[i])+a[i],dp(i-1,j,c)} 
    dp(2N,N,SUM/2+1)就是题目的解。 
    */  
    //初始化  
    memset(dp,0,sizeof(dp));  

    for(i = 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值