Fantasy Festival
题意:
有n组小队,每组都有男生和女生,
-
随便选,无要求。
-
求男女生差值最小的所有选法中,所选组数最小的方案。
题解:
求差值,如何定义差值?
不妨将男生数量定为正数,女生数量定为负数,这样对于每组来说,被选择后加到整体里面也具有统一的意义。
但是,数组不能有负下标,所以我们将所有值均加上了35000,使得负数也能以正数形式存在。(就是处理起来很麻烦,而且化为1维也比较麻烦。(倒序和正序)
倒序原因:
同样是因为覆盖问题,当全为正数时,要从最大值开始,而这里的负数,实际意义上也是正数,只是方向不同而已,所有从绝对值较大的方向开始枚举。
二维背包
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
// #define int long long
#define _u_u_ ios::sync_with_stdio(false), cin.tie(nullptr)
int mod = 1e9 + 7;
const int maxn = 1e5 + 10;
const int inf = 0x3f3f3f3f;
int f[37][35010 * 2];
inline void _A_A_() {
int n;
cin >> n;
vector<pair<int,int>> v(n + 2);
for (int i = 1;i <= n;i++) {
cin >> v[i].first >> v[i].second;
v[i].first += 35000;
v[i].second += 35000;
}
memset(f,-0x3f,sizeof f);
f[0][35000] = 0;
int ans2 = inf;
for (int i = 1;i <= n;i++) {
for (int j = 0;j <= 35000 * 2;j ++) {
f[i][j] = f[i - 1][j];
if (j >= (v[i].first - v[i].second))
f[i][j] = max(f[i][j], f[i - 1][j - (v[i].first - v[i].second)] + 1);
}
}
for (int j = 0;j <= 35000 * 2;j ++) {
if (f[n][j] <= 35&&f[n][j] > 0 && abs(j - 35000) < abs(ans2 - 35000) ) {
ans2 = j;
}
}
int ans = abs(ans2 - 35000);
cout << ans << " " << max(f[n][35000+ans] , f[n][35000-ans])<< "\n";
}
signed main() {
_u_u_;
int _o_o_ = 1;
// cin >> _o_o_;
while (_o_o_--){_A_A_();}return 0;
}
一维背包
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
// #define int long long
#define _u_u_ ios::sync_with_stdio(false), cin.tie(nullptr)
int mod = 1e9 + 7;
const int maxn = 1e5 + 10;
const int inf = 0x3f3f3f3f;
int f[35010 * 2];
inline void _A_A_() {
int n;
cin >> n;
vector<pair<int,int>> v(n + 2);
for (int i = 1;i <= n;i++) {
cin >> v[i].first >> v[i].second;
v[i].first += 35000;
v[i].second += 35000;
}
memset(f,-0x3f,sizeof f);
f[35000] = 0;
int ans2 = inf;
for (int i = 1;i <= n;i++) {
if ((v[i].first - v[i].second) > 0)
for (int j = 35000 * 2 ; j >= (v[i].first - v[i].second);j --)
f[j] = max(f[j], f[j - (v[i].first - v[i].second)] + 1);
else
for (int j = 0; j <= (35000 * 2 + (v[i].first - v[i].second));j++)
f[j] = max(f[j], f[j - (v[i].first - v[i].second)] + 1);
}
for (int j = 0;j <= 35000 * 2;j ++) {
if (f[j] <= 35&&f[j] > 0 && abs(j - 35000) < abs(ans2 - 35000) ) {
ans2 = j;
}
}
int ans = abs(ans2 - 35000);
cout << ans << " " << max(f[35000+ans] , f[35000-ans])<< "\n";
}
signed main() {
_u_u_;
int _o_o_ = 1;
// cin >> _o_o_;
while (_o_o_--){_A_A_();}return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App