又是dp,真的是我不会什么最近就整什么,哈哈哈,不过也没关系,可以学习一下,不过过段时间要系统的学一下
推理过程:
- 这个意思就是说把所有的东西分成2堆,求他们的差值最小
- 转换一下也就是求一半时的值的最大值(01背包)
- 然后直接套01背包就OK,这里第一层循环是代表每一个的值,
- 第二层循环是可以取的值来变换
- 这里需要注意的是dp数组需要开大一点,因为是res / 2,res可以达到1e4,所以保险起见开到1e4即可(这里wa了)
相关代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 10010;
int dp[N];
int a[N];
int main(){
int n;
scanf("%d",&n);
int res = 0;
for (int i = 1; i <= n; i++){
scanf("%d",&a[i]);
res += a[i];
}
for(int i = 1; i <= n; i++){
for (int j = res / 2; j >= a[i]; j --){
dp[j] = max(dp[j], dp[j - a[i]] + a[i]);
}
}
printf("%d %d\n",dp[res/2],res - dp[res/2]);
return 0;
}