牛客网暑期ACM多校训练营(第三场)A - PAXM Team(01背包)

题目链接

思路

多重限制条件的01背包,输出选取那几小组,可以开个bool数组记录选取物品时的状态,然后从最后一个物品往上找标记。

后记

这道题比赛的时候数据太水,简单排序选一件物品就行,看别人代码还有直接输出零过了。。。比赛结束1小时左右,加强数据了,还好提前过了 ^ _ ^
物品标记当时想错了,赛后看看学长代码真的强

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <map>
#include <bitset>
#include <set>
#include <string.h>
#include <cmath>
#include <queue>
#include <algorithm>
#define N 40
#define ll long long
#define lowbit(a) a&(-a)
#define pb(a) push_back(a)
#define mk(a, b) make_pair(a, b)
#define mem(a, b) memset(a, b, sizeof(a))
#define read(a) scanf("%d", &a)
#define print(a) printf("%d\n", a)
using namespace std;
struct group{
    int p, a, c, m, g;
}a[N];
// 也可以开4个数组存每个小组信息,因为没有问最大的分值
int dp[N][N][N][N];
bool vis[N][N][N][N][N];
int main(){

#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif
    int n, P, A, M, C, G;
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) {
        scanf("%d%d%d%d%d", &a[i].p, &a[i].a, &a[i].c, &a[i].m, &a[i].g);
    }
    scanf("%d%d%d%d", &P, &A, &C, &M);
    for (int i = 0; i < n; ++i) {
        for (int j = P; j >= a[i].p; --j) {
            for (int k = A; k >= a[i].a; --k) {
                for (int l = C; l >= a[i].c; --l) {
                    for (int r = M; r >= a[i].m; --r) {
                        if (dp[j - a[i].p][k - a[i].a][l - a[i].c][r - a[i].m] + a[i].g > dp[j][k][l][r]) {
                            dp[j][k][l][r] = dp[j - a[i].p][k - a[i].a][l - a[i].c][r - a[i].m] + a[i].g;
                            // 将当前状态标记
                            vis[i][j][k][l][r] = true;
                        }
                    }
                }
            }
        }
    }
    vector<int> wu;
    // 从最后一个物品向前找标记
    for (int i = n - 1, j = P, k = A, l = C, r = M; i >= 0; --i) {
        if (vis[i][j][k][l][r]) {
            wu.push_back(i);
            j -= a[i].p;
            k -= a[i].a;
            l -= a[i].c;
            r -= a[i].m;
        }
        if (j < 0 || k < 0 || l < 0 || r < 0)
            break;
    }
    if (wu.empty()) {
        printf("%d\n", 0);
    }else {
        printf("%d\n", wu.size());
        sort(wu.begin(), wu.end());
        for (auto it : wu) {
            printf("%d ", it);
        }
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/henuyh/article/details/81226161
今日推荐