Fantasy Festival

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;
}
posted @   Uzhia  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
点击右上角即可分享
微信分享提示