Nowcoder186C 失衡天平 背包

题目传送门

题意:给你$N$个数,你可以将其划分为若干对集合(这里所说的集合允许数字重复)(即集合是两个集合两个集合出现),每对集合中两个集合所有元素的和的差的绝对值不超过$M$,可以有数字不在集合内,可以有集合为空。求所有集合内数的和的最大值。$N \leq 100 , M \leq 100$,数字$\leq 100$


虽然考试的时候没做出来但还是感觉这是一道大水题

可以发现:划分若干对集合和划分一对集合是等效的,因为假如说一对集合$A,B$中$\sum A \leq \sum B(\sum A$表示集合$A$中所有元素的和$)$,另一对集合$C,D$满足$\sum C \leq \sum D$,那么集合$A+D,B+C$一定是满足条件的(显然)。所以我们就是要划分两个集合使得其差的绝对值不超过$M$且和最大。经典的01背包拔河问题

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 int dp[20010] , pot[20010];
 5 
 6 int main(){
 7     ios::sync_with_stdio(0);
 8     cin.tie(0);
 9     cout.tie(0);
10     int N , M;
11     cin >> N >> M;
12     memset(pot , -0x3f , sizeof(pot));
13     memset(dp , -0x3f , sizeof(dp));
14     dp[10000] = 0;
15     for(int i = 1 ; i <= N ; i++){
16         int a;
17         cin >> a;
18         for(int j = a ; j <= 20000 ; j++)
19             pot[j - a] = max(pot[j - a] , dp[j] + a);
20         for(int j = 0 ; j <= 20000 - a ; j++)
21             pot[j + a] = max(pot[j + a] , dp[j] + a);
22         for(int j = 0 ; j <= 20000 ; j++)
23             dp[j] = max(dp[j] , pot[j]);
24     }
25     int ans = 0;
26     for(int i = 10000 ; i <= 10000 + M ; i++)
27         ans = max(ans , dp[i]);
28     cout << ans;
29     return 0;
30 }

 

转载于:https://www.cnblogs.com/Itst/p/9775506.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值