AcWing 1013. 机器分配(分组背包求具体方案)

题目链接:点击这里

在这里插入图片描述
在这里插入图片描述

如上图关系,可考虑成一个分组背包问题。

每个子公司相当于一个物品组,即有 N N 个物品组,每个物品组里有 M + 1 M+1 个物品,即分配 0 0 台、分配 1 1 台、分配 2 2 台 … 分配 m m 台,并且同一组内的物品最多只能选一个。

输出方案时从后往前推,记录当前状态是由哪个状态转移来的,最后再顺序输出。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>

using namespace std;

const int N = 11, M = 16;

int n, m;
int w[N][M];
int f[N][M];
int path[N];

int main()
{
    scanf("%d%d", &n, &m);       // n是物品组数,m是背包容量
    
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j)
            scanf("%d", &w[i][j]);
    
    for(int i = 1; i <= n; ++i)         // 依次枚举每一个物品组
    {
        for(int j = 0; j <= m; ++j)     // 再枚举体积
        {
            for(int k = 0; k <= j; ++k) // 再枚举决策
            {
                f[i][j] = max(f[i][j], f[i - 1][j - k] + w[i][k]);
            }
        }
    }
    
    printf("%d\n", f[n][m]);
    
    int vol = m;
    for(int i = n; i; --i)      // 从后往前推
    {
        for(int j = 0; j <= vol; ++j)
        {
            if(f[i][vol] == f[i-1][vol-j] + w[i][j])
            {
                path[i] = j;
                vol -= j;
                break;
            }
        }
    }

    for(int i = 1; i <= n; ++i)
        printf("%d %d\n", i, path[i]);
    
    return 0;
}
发布了822 篇原创文章 · 获赞 127 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/qq_42815188/article/details/104967428
今日推荐