zoukankan      html  css  js  c++  java
  • 【2016级学长的邀请赛】Problem B 空門蒼的祭典

    传送门

    • 空門蒼负责的祭典人手不够了,现在她需要求助你会。可惜的是,你会人手也不够了,所以你会会长yyh需要女装来纳新。

    现有n个职位,每个职位只能纳一个人,这届有m个萌新,每个萌新只能胜任一个职位,每个萌新都有自己的实力值与需求值,你会会长可以通过女装来满足他们的需求值,但你会会长最多也只能满足s的需求值(即纳到的萌新需求值≤s),在社长的能力范围之内,要让纳到的萌新实力值之和最大,问最大值为多少。

    输入

    第一行分别为 n,m,s
    接下来有 m 行,每行有三个数字 x,y,z 分别代表这个萌新能胜任的位置(以数字 1-n 来表示),实力值,需求值

    输出

    输出为一个数字,代表最大的实力值之和

    输入样例

    3 9 10
    1 4 2
    1 7 5
    1 8 10
    2 6 2
    2 7 2
    2 8 2
    3 4 6
    3 7 7
    3 8 2

    输出样例

    23

    提示

    对于20%的数据, m<=20, n<=20, s<=100
    对于50%的数据, m<=500, n<=500, s<=1000
    对于100%的数据, m<=5000, n<=5000, s<=5000


    我相信你一眼就看出来这是道DP题

    所以只要用分组背包的思路做就可以轻松AC了

    分组背包和普通背包的差别:

    这个问题变成了每组物品有若干种策略:

    是选择本组的某一件,还是一件都不选。

    也就是说设 f [ k ] [ j ] 表示前 k 组物品花费费用 j 能取得的最大权值,则有:

    f[k][j]=max(f[k−1][j],f[k−1][j−c[i]]+w[i]∣物品i属于组k)
    

    核心伪代码:

    for (所有的组k)
        for (int j = V; j >= 0; j--)
            for (所有属于组k的i)
                f[j] = max{f[j], f[j - w[i]] + v[i]}
    

    注意这里的三层循环的顺序, f o r ( j . . . 0 )

    这一层循环必须在 for (所有的 i 属于组 k)之外。

    这样才能保证每一组内的物品最多只有一个会被添加到背包中。

    另外,显然可以对每组内的物品应用完全背包中“一个简单有效的优化”。

    • 小结

    分组的背包问题将彼此互斥的若干物品称为一个组,这建立了一个很好的模型。

    不少背包问题的变形都可以转化为分组的背包问题(例如有依赖的背包),由分组的背包问题进一步可定义“泛化物品”的概念,十分有利于解题。

    以下是AC代码:

    //By Mitruha
    //Date : 2020 10 23
    //分组背包 
    #include <bits/stdc++.h>
    using namespace std;
    const int Maxn = 5010;
    
    int v[Maxn], w[Maxn];
    int a[Maxn][Maxn];
    int opt[Maxn];
    int n, m, s, group;
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
    
        cin >> n >> m >> s;
        for(int i = 1;i <= m; i++)
        {
            cin >> group >> w[i] >> v[i];
            a[group][++a[group][0]] = i;
        }
    
        for(int i = 0; i < s; i++)
            for(int j = m ; j >= 0 ; j--)
                for(int k = 1;k <= a[i][0]; k++)
                    if(j - v[a[i][k]] >= 0)
                        opt[j] = max(opt[j], opt[j - v[a[i][k]]] + w[a[i][k]]);
    
        cout << opt[m] << "
    ";
        return 0;
    }
    
  • 相关阅读:
    办公室搞笑记(2) 李姐
    世界上疼我的人又少了一个
    带给杨帆的祝福:)
    火:) 火:) 火:)
    我们都是享受寂寞的孩子:)
    복 경 에 갑 니 다 :) 去北京.
    너는 겨울이 좋아요 .我喜欢冬天:)
    2007年:新年,新开始:)
    Nginx 泛域名配置方式
    数据库设计 从零开始系列之一
  • 原文地址:https://www.cnblogs.com/misaka1932/p/14088709.html
Copyright © 2011-2022 走看看