zoukankan      html  css  js  c++  java
  • P1757 通天之分组背包

    题目链接:https://www.luogu.com.cn/problem/P1757

    b就是在01背包的基础上对每个物品添加了组数,就变成了分组背包。

    考虑到01背包的状态转移方程dp[j]=max(dp[j],dp[j-a[i]]+b[i]),分组背包和它相同.

    那么怎么填这个表呢,在01背包中,通过俩层for循环来实现,第一层for是控制第i到n个拿不拿,在分组背包中,这个问题就变成了第i个到n组拿不拿。然后套01背包就可以了。

    简单写就是for(i,num)//第1组到第num组

                         for(,)//01背包

                           for(,)

    需要注意的是确定每个物品的位置,所以需要开个二维数组来存,f[第几组][第几个]

    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define INF 0x7fffffffffffffff
    typedef long long ll;
    const double PI=3.1415926535897931;
    const long long mod=1e9+7;
    const int MA= 1e7+10;
    const int ma= 2*1e6+10;
    const int few=1e3+10;
    using namespace std;
    //////////////////////////////////////////////
    
    int dp[ma];
    int a[ma];
    int b[ma];
    int c[ma];
    int f[few][few];
    int num;
    int cnt[ma];
    int main()
    {
        int m,n;
        cin>>m>>n;
        for(int i=1; i<=n; i++)
        {
            cin>>a[i]>>b[i]>>c[i];
            num=max(num,c[i]);//找最大的组数
            cnt[c[i]]++;统计每个组的数
            f[c[i]][cnt[c[i]]]=i;记录成员的位置,方便后面的访问
        }
        for(int k=1; k<=num; k++)//第1组到第num组
            for(int j=m; j>=0; j--)//01背包
                for(int i=1; i<=cnt[k]; i++)
                {
                    int tmp=f[k][i];
                    if(j>=a[tmp])
                        dp[j]=max(dp[j],dp[j-a[tmp]]+b[tmp]);//熟悉的状态转移方程
                }
        cout<<dp[m]<<endl;
        return 0;
    }
  • 相关阅读:
    String和stringbuffer
    项目中Orcale存储过程优化记录
    大数据项目中的Oracle查询优化
    洛谷P3402 可持久化并查集
    Gym
    CodeForces
    Gym
    Gym
    UVA
    Kattis
  • 原文地址:https://www.cnblogs.com/Aracne/p/12567636.html
Copyright © 2011-2022 走看看