UVA 562 Dividing coins(01 背包问题)

将基础的01背包 稍微的转化了一点,、

题意就是让你求出N个硬币,然后分成两组求两组的差值最小为多少,不能为负、 

大概思路就是如果我想要找到最小的值的话,那么我们首先是知道所有得数的和sum,既然想找到差值最小,只需要求以(sum/2) 位容量,每个硬币的值为单位容量、

只要求出满足容量的最大值便可以了、  

分析:因为是想要找出N个硬币分成两组合值的差值值的最小值,所以我们可以先求一组我想要的值,既然知道所有硬币的总值sum,所以当然我想要满足其中一组

的最大值为sum/2是最好的,但是它不一定可以为sum/2,所以就要求出在尽量装满sum/2的最大值、 所以最小的差值为sum-dp[N]*2、


代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=110000;
int T;
int N;
int V;
int VV;
int w[maxn];
int dp[maxn];
int main()
{
    scanf("%d",&T);
    while(T--){
        scanf("%d",&N);
        V=0;
        memset(dp,0,sizeof(dp));
        for(int i=0;i<N;i++){
            scanf("%d",&w[i]);
            V+=w[i];
        }
        VV=V/2;
        for(int i=0;i<N;i++){
            for(int j=VV;j>=w[i];j--){
                dp[j]=max(dp[j],dp[j-w[i]]+w[i]);
            }
        }
        printf("%d\n",V-dp[VV]*2);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值