每日一题——拔河问题

题目描述
小明班里要举行一次拔河比赛,班主任决定将所有人分为两队,每个人都必须参加。两个队伍的人数之差不能超过1,并且两个队伍的体重之和要尽可能相近,当然相同是最好的了。
输入
输入包含多组测试数据。
每组输入的第一行是一个正整数n(2<=n<=100),表示共有n个人。
接下来n行,每行输入一个整数w(1<=w<=450),表示每个人的体重。
输出
对于每组输入,分别输出两个队伍的体重之和,按升序排序。
样例输入 Copy
3
100
90
200
样例输出 Copy
190 200

因为多了一个限制,也就是分成两队的人数之间的差距不能大于1,所以我们在推导递推式的时候还要考虑总人数的影响,也就是再加一个变量,将其变成二维的,一个代表人数,一个代表总重量。

点击查看代码
#pragma GCC optimize(1) #pragma GCC optimize(2) #pragma GCC optimize(3,"Ofast","inline") #include<bits/stdc++.h> typedef long long ll; using namespace std; const int N = 110, M = 500 * N; int dp[N][M], a[N], sum;//因为人数相差不能大于1,所以dp要多一个位置用于记录人数 int main() { int n, i, j, k; while (scanf("%d", &n) != EOF) { memset(dp, 0, sizeof(dp)); sum = 0; for (i = 1; i <= n; i++) { scanf("%d", &a[i]); sum += a[i]; } dp[0][0] = 1; for (i = 1; i <= n; i++) { for (k = sum / 2; k >= a[i]; k--)//k代表总体重 {//不知道为什么k和j不能互换位置 for (j = 1; j <= (n + 1) / 2; j++)//j代表总人数 { if (dp[j - 1][k - a[i]])//类似于递推,由j-1个人k-a[i]的总体重推到j个人k的总体重 { dp[j][k] = 1; } } } } for (i = sum / 2; i >= 0; i--)//从sum/2开始遍历,左边就会是较小的那个 { if (dp[n / 2][i] || dp[n / 2 + 1][i]) { printf("%d %d\n", i, sum - i); break; } } } return 0; }

__EOF__

本文作者母鸡
本文链接https://www.cnblogs.com/myy-zzb/p/17165760.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   美羊羊给沸羊羊搬砖  阅读(232)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示