zoukankan      html  css  js  c++  java
  • 动态规划-分组背包问题

    https://vjudge.net/contest/297216?tdsourcetag=s_pctim_aiomsg#problem/K

    3(物品组数) 3(时间)

    f[i,j]表示完成了前i件任务,
    背包容量为j时所能达到的最大价值。
    f[i-1,j-cost]+val;
    2 1 最多选一件
    2 5
    3 8

    2 0 至少选一件
    1 0
    2 1

    3 2 自由选
    4 3
    2 1
    1 1

    #include<bits/stdc++.h>
    using namespace std;
    #define LL long long
    const int INF=0x3f3f3f3f;
    const int maxn=105;
    int cost[maxn];
    int val[maxn];
    int f[maxn][maxn];
    int main()
    {
        int m,t;
        while(scanf("%d%d",&m,&t)==2) // 不写==2会超时!!
        {
            memset(f,0,sizeof(f));
            for(int i=1; i<=m; i++)
            {
                int n,type;
                scanf("%d%d",&n,&type);
                for(int j=1; j<=n; j++)
                    scanf("%d%d",&cost[j],&val[j]);
                if(type==0)
                {
                    // 背包初始化要从0开始,而不是1
                    for(int j=0; j<=t; j++) f[i][j]=-INF;
                    // 将新判断的一组物品,开始时不同背包容量的价值都初始化为负数,保证至少选入这个物品。
                    for(int j=1; j<=n; j++)
                        for(int k=t; k>=cost[j]; k--) // k要倒着枚举,保证不重复选取。
                        {
    
                            f[i][k]=max(f[i][k],f[i][k-cost[j]]+val[j]);
                            f[i][k]=max(f[i][k],f[i-1][k-cost[j]]+val[j]);
                            // 这两个写反了会错,为什么?
                        }
                }
                else if(type==1)
                {
                    for(int k=0; k<=t; k++) f[i][k]=f[i-1][k];
                    for(int j=1; j<=n; j++)
                        for(int k=cost[j]; k<=t; k++)// 这个k可正序也可反序枚举
                        {
                            f[i][k]=max(f[i][k],f[i-1][k-cost[j]]+val[j]);
                        }
                }
                else
                {
                    //  标准1维数组优化的01背包问题,
                    for(int k=0; k<=t; k++) f[i][k]=f[i-1][k];
                    for(int j=1; j<=n; j++)
                        for(int k=t; k>=cost[j]; k--)
                        {
                            f[i][k]=max(f[i][k],f[i][k-cost[j]]+val[j]);
                        }
                }
            }
            int ans=max(f[m][t],-1);
            printf("%d
    ",ans);
        }
    }
  • 相关阅读:
    相机标定/校正(Camera Calibration)
    彩色图像直方图均衡(Histogram Equalization)
    SQL--数据的检索
    SQL--数据的增删改
    SQL--数据库的创建与管理
    java学习笔记之异常、断言
    Mysql学习笔记(二)
    初学机器学习(一)
    Mysql学习笔记(一)
    软件课设Day15
  • 原文地址:https://www.cnblogs.com/dongdong25800/p/10789569.html
Copyright © 2011-2022 走看看