背包(01,完全,多重,分组)

01背包

#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
    int m,n,dp[100005];
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        int w,p;
        scanf("%d%d",&w,&p);
        for(int j=m;j>=w;j--)
        {
            dp[j]=max(dp[j-w]+p,dp[j]);
        }
    }
    printf("%d\n",dp[m]);
    return 0;
}

完全背包

#include <cstdio>
#include <iostream>
using namespace std;
int f[1005],v[1005],w[1005];
int main()
{
    int n,m,ans;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
      scanf("%d%d",&v[i],&w[i]);
    for(int i=1;i<=n;i++)
    {
        for(int j=v[i];j<=m;j++)
        {
            f[j]=max(f[j],f[j-v[i]]+w[i]);
        }
    }
    printf("%d\n",f[m]);
    return 0;
}

多重背包(优化)

#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
int f[2005];
struct Good{
    int v,w;
};
vector <Good> goods;
int main()
{
    int n,m,ans,s,v,w;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d%d",&v,&w,&s);
        for(int k=1;k<=s;k*=2)
        {
            s-=k;
            goods.push_back({v*k,w*k});
        }
        if(s>0) goods.push_back({v*s,w*s});
    }
    for(auto good:goods)
    {
        for(int j=m;j>=good.v;j--)
        {
            f[j]=max(f[j],f[j-good.v]+good.w);
        }
    }
    printf("%d\n",f[m]);
    return 0;
}

分组背包

#include <cstdio>
#include <iostream>
const int M=1010;
using namespace std;
int main()
{
    int m,n,w[M],p[M],arr[110][M],ar[M],num=0,dp[M];
    scanf("%d%d",&m,&n);
    for(int i=1;i<=n;i++)
    {
        int a;
        scanf("%d%d%d",&w[i],&p[i],&a);
        num=max(num,a);
        ar[a]++;
        arr[a][ar[a]]=i;
    }
    for(int i=1;i<=num;i++)
    {
        for(int j=0;j<=m;j++)
        {
            for(int k=1;k<=ar[i];k++)
            {
                int f=arr[i][k];
                if(j+w[f]<=m)
                  dp[j]=max(dp[j],dp[j+w[f]]+p[f]);
            }
        }
    }
    printf("%d\n",dp[0]);
    return 0;
}

混合背包

#include <cstdio>
#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
const int M=1010;
using namespace std;
struct Good{
    int kind;
    int w,p;
};

vector <Good> goods;
int main()
{
    int m,n,dp[M];
    memset(dp,0,sizeof(dp));
    cin>>n>>m;
    for(int i=0;i<n;i++)
    {
        int w,p,s;
        cin>>w>>p>>s;
        if(s<0)
        {
            goods.push_back({-1,w,p});
        }
        else if(s==0)
        {
            goods.push_back({0,w,p});
        }
        else
        {
            for(int k=1;k<=s;k*=2)
            {
                s-=k;
                goods.push_back({-1,w*k,p*k});
            }
            if(s>0)
            goods.push_back({-1,w*s,p*s});
        }
    }
    for(auto good:goods)
    {
        if(good.kind<0)
        {
            for(int j=m;j>=good.w;j--)
                dp[j]=max(dp[j],dp[j-good.w]+good.p);
        }
        else
        {
            for(int j=good.w;j<=m;j++)
                dp[j]=max(dp[j],dp[j-good.w]+good.p);
        }
    }
    cout<<dp[m]<<endl;
    return 0;
}

原文地址:https://www.cnblogs.com/zptcszj/p/11643836.html

时间: 2024-11-02 22:17:50

背包(01,完全,多重,分组)的相关文章

HDU 3591 The trouble of Xiaoqian(多重背包+01背包)

HDU 3591 The trouble of Xiaoqian(多重背包+01背包) http://acm.hdu.edu.cn/showproblem.php?pid=3591 题意: 有一个具有n种货币的货币系统, 每种货币的面值为val[i]. 现在小杰手上拿着num[1],num[2],-num[n]个第1种,第2种-第n种货币去买价值为T(T<=20000)的商品, 他给售货员总价值>=T的货币,然后售货员(可能,如果小杰给的钱>T, 那肯定找钱)找钱给他. 售货员每次总是用

HDU1864_最大报销额(背包/01背包)

解题报告 题目传送门 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define inf 99999999 using namespace std; int v,w[35],d[4],dw1,sum,dp[31*1000*100]; int main() { double Q,dw; int n,i,j,m,t; char c; while(~sc

HDU2602_Bone Collector(背包/01背包)

解题报告 题目传送门 题意: 容量为v的大小,物品数n,每个物品有价值和容量,求能装进包的最大价值. 思路: 基础01背包. dp[j]=max(dp[j],dp[j-c[i]]+w[i]) #include <iostream> #include <cstring> #include <cstdio> #define inf 99999999 using namespace std; int main() { int t,i,j,n,v,w[1010],c[1010]

POJ3260——背包DP(多重)——The Fewest Coins

Description Farmer John has gone to town to buy some farm supplies. Being a very efficient man, he always pays for his goods in such a way that the smallest number of coins changes hands, i.e., the number of coins he uses to pay plus the number of co

【CJWYH】RHL的背包题解(多重背包)

题面 [问题描述] CJ中学组织学生出去春游,作为学神的RHL自然不会放过这一大好时机,他有n种物品,第i件物品有c[i]个,每个体积为v[i],价值为w[i],RHL现在有一个体积为V的背包,他想让他带的东西价值之和最大,且体积之和不超过V,你能帮帮他吗?注意物体不能分割. [输入] 输入文件名为bag.in,分为若干行.第一行包含两个正整数n,V. 第二行到第n+1行分别描述第i种物品的数量c[i],体积v[i],价值w[i] [输出] 输出文件名为bag.out,一行输出一个整数,表示最大

分组背包(通天之分组背包)

分组背包是01背包的变形. 所解决的问题是,在多类物品中的每一类选出一个物品,在有限的容量内获得最大价值. 所注意的是3重for的顺序.在这里其实不用多讲,只要明白递归就可以了. 建议搜分组背包的博客,其实只要记住最后才是每一类中放还是不放物品即可. 例题: 通天之分组背包 题目背景 直达通天路·小A历险记第二篇 题目描述 自01背包问世之后,小A对此深感兴趣.一天,小A去远游,却发现他的背包不同于01背包,他的物品大致可分为k组,每组中的物品相互冲突,现在,他想知道最大的利用价值是多少. 输入

完全背包——01背包方法数

这两天搞完01背包之后学习了完全背包这个完全背包是指物品数量无限,让自己来装考虑一下状态转移f[i][j]=max(f[i-1][j])尚未选择第i种物品,f[i][j]=max(f[i][j-w[i]+v[i]]);从第i键物品中选择一个显然状态是由不拿当前物品上一层的最优解和当前拿这个物品的最优解来进行比较从而进行转移.当然目标可以是maxf[n][j]或者是f[n][m]这两种都行只不过前者可以判断背包是否能被装满. 下面是二维的代码: #include<ctime> #include&

dp--分组背包 P1757 通天之分组背包

题目背景 直达通天路·小A历险记第二篇 题目描述 自01背包问世之后,小A对此深感兴趣.一天,小A去远游,却发现他的背包不同于01背包,他的物品大致可分为k组,每组中的物品相互冲突,现在,他想知道最大的利用价值是多少. 输入格式 两个数m,n,表示一共有n件物品,总重量为m 接下来n行,每行3个数ai,bi,ci,表示物品的重量,利用价值,所属组数 输出格式 一个数,最大的利用价值 有容积为V的背包,有n件物品,每种物品属于的组别不同,t为最大的组数,每组中的物品相互冲突,所以只能选其中一件 接

饭卡 (背包01) http://acm.hdu.edu.cn/showproblem.php?pid=2546

/* 从一组数据中选出n个数,使这n个数的和最接近一个值x, 背包问题, 从一系列菜中,从最贵的菜(MAX)之外中选出几个菜,使菜的总价格sum最接近money-5:money-sum-MAX; 钱数相当于背包总容量,菜相当于价值和体积一样物品: */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int d

ACboy needs your help(背包九讲_分组背包)

ACboy needs your helpCrawling in process... Crawling failed Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description ACboy has N courses this term, and he plans to spend at most M days on study.Of course,