- 题目考点:dp -- 01背包 (无脑dfs肯定T ,后面附上60分dfs吧)
- 题目大意:将a数组中的数分成两组,使得两组中的数的和尽量接近,输出两组数的和(若无法平均,优先输出较小的数)
- 题目分析:01背包问题,若a数组中的数总和为sum ,可以假想一个体积为sum / 2的背包,将其尽量装满即可
代码如下:
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 10010; // 100个苹果每个质量都是100的话,需要一个10000的背包
//所以dp数组至少需要5000, 这里奢侈了一把
int a[N], n, sum = 0;
int dp[N];
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]), sum += a[i];
int v = sum / 2;
for(int i = 1; i <= n; i++)
for(int j = v; j >= a[i]; j --)
dp[j] = max(dp[j], dp[j - a[i]] + a[i]);
printf("%d %d", dp[v], sum - dp[v]);
return 0;
}60分dfs给大家助助兴:
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 110, INF = 0x3f3f3f3f;
int a[N], sum = 0, n;
int ans = 0;
bool v[N];
void dfs(int w, int k)
{
if(k > n){ans = max(ans, w); return ;}
if(w + a[k] <= sum / 2)
dfs(w + a[k], k + 1);
dfs(w, k + 1);
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]), sum += a[i];
dfs(0, 1);
printf("%d %d", ans, sum - ans);
return 0;
}
京公网安备 11010502036488号