poj2576 Tug of War

本文介绍了一种使用二维背包算法解决特定数字分组问题的方法。问题要求将n个数分为两组,每组数量相差不超过1,目标是使两组数字总和之差最小。通过设定状态dp[j][k]表示是否存在一组由k个数构成,其值为j,以数字总和一半和数量一半为上限进行状态转移,从而高效求解。

Topic Links

Topic Meaning:给出n个数从中选a个数构成一组,剩下的b个数为一组,a与b的差值不超过1,求这两组数字总和差值最小时的两组的值。

Method of Solving:二维背包

dp[j][k]表示是否存在一组当其有k个数时,其值为j,以所有数字总和sum/2为第一状态上限,数字个数n/2为第二状态上限进行状态转移即可;

因为当dp[j][k]确定时,必然可知另外一组含n-k个数字,其数字总和为sum-j,结合题目要求可得出答案;

 

#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
int f[105],dp[50000][105];
int main(){
    int n,sum;
    while(cin>>n){
    sum=0;
    for(int i=1;i<=n;i++) {cin>>f[i];sum+=f[i];}
    int mid=sum/2,half=(n+1)/2;
    memset(dp,0,sizeof(dp));
    dp[0][0]=1;
    for(int i=1;i<=n;i++)
        for(int j=mid;j>=f[i];j--)
        for(int k=half;k>0;k--)
        if(dp[j-f[i]][k-1])
        dp[j][k]=1;
    int maxl=0,j;
    for(j=mid;j>=0;j--)
        if(dp[j][half]||dp[j][half-1])
        break;
    cout<<j<<' '<<sum-j<<endl;
    }
return 0;
}

  

转载于:https://www.cnblogs.com/WELOTX/p/11391287.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值