【结论&例题】背包动规

40 篇文章 0 订阅
26 篇文章 0 订阅

1、
(1)、一个背包容积为T(0<=T<=2000),现在有N(0< N<=1000)个物品,每个物品有一定体积V(1<=V<=5000)。从这N个物品中选取若干个装入背包内,使背包所剩的空间最小。请求出最小的剩余空间?
(2)、若每种物品有无限个,请求出最小的剩余空间

状态:f[j]表示能否选取若干个物品放入背包中,使背包已使用的体积恰好为j,能为true,不能为false

#include<cstdio>
using namespace std;

int a[1002];
bool f[2002];

int main()
{
    int t,n;
    scanf("%d%d",&t,&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    f[0]=1;
    for(int i=1;i<=n;i++)
     for(int j=t;j>=a[i];j--)//一个
     //for(int j=a[i];j<=t;j++)//无限个
     {
        if(f[j-a[i]]==1) f[j]=1;
     }
    for(int i=t;i>=0;i--) 
    {
        if(f[i]==1) 
        {
            printf("%d",t-i);
            break;
        }
    }
}

2、
(1)、一个背包容积为T(0<=T<=2000),现在有N(0< N<=1000)个物品,每个物品有一定体积V(1<=V<=5000)。每个物品有一定价值W(1<=W<=5000)。从这N个物品中选取若干个装入背包内,使背包总价值最大。请求出最大价值。
(2)、若每种物品有无限个,请求出最大价值。

状态:f[j]表示容积为j的背包,能装下的物品的最大价值。(j不一定要恰好用完)
方程:f[j]=max(f[j],f[j-v[i]]+w[i]);

#include<cstdio>
#include<iostream>
using namespace std;

int f[2003],v[1003],w[1003];

int main()
{
    int t,n;scanf("%d%d",&t,&n);
    for(int i=1;i<=n;i++) scanf("%d",&v[i]);
    for(int i=1;i<=n;i++) scanf("%d",&w[i]);
    //初值f[0][0]=0,其它为-inf(0也无妨)
    for(int i=1;i<=n;i++)
     for(int j=t;j>=v[i];j--)//一个
     //for(int j=v[i];j<=t;j++)//无限
     {
        f[j]=max(f[j],f[j-v[i]]+w[i]);
     }
    printf("%d",f[t]);
}

3、有两个背包,一个容积为A,一个容积为B,现在有N个物品,每个物品有一定体积V。每个物品有一定的价值W。从这N个物品中选取若干个装入背包内,使背包内物品的价值最大。请求出最大价值?

状态:f[i][j]表示第一个背包容积为i,第二个背包容积为j时,能得到的最大价值。(不一定要恰好用完)
方程:f[i][j]=max{ f[i-v[k]][j]+w[k],f[i][j-v[k]]+w[k],f[i][j]} (j>=v[k],i>=v[k])

#include<cstdio>
#include<iostream>
using namespace std;

int f[303][303],v[303],w[303];

int main()
{
    int n,a,b;scanf("%d%d%d",&n,&a,&b);
    for(int i=1;i<=n;i++) scanf("%d",&v[i]);
    for(int i=1;i<=n;i++) scanf("%d",&w[i]);
    //初值f[0][0]=0,其它为-inf(0也无妨)
    for(int k=1;k<=n;k++)
     for(int i=a;i>=0;i--)
      for(int j=b;j>=0;j--)
      {
        if(i>=v[k]) f[i][j]=max(f[i][j],f[i-v[k]][j]+w[k]);
        if(j>=v[k]) f[i][j]=max(f[i][j],f[i][j-v[k]]+w[k]);
      }
    printf("%d",f[a][b]);
}

4、
装满两个背包,且使总权值最小
http://blog.csdn.net/Y__XV/article/details/52733436

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
买书问题 dp实现 题目:买书 有一书店引进了一套书,共有3卷,每卷书定价是60元,书店为了搞促销,推出一个活动,活动如下: 如果单独购买其中一卷,那么可以打9.5折。 如果同时购买两卷不同的,那么可以打9折。 如果同时购买三卷不同的,那么可以打8.5折。 如果小明希望购买第1卷x本,第2卷y本,第3卷z本,那么至少需要多少钱呢?(x、y、z为三个已知整数)。 1、过程为一次一次的购买,每一次购买也许只买一本(这有三种方案),或者买两本(这也有三种方案), 或者三本一起买(这有一种方案),最后直到买完所有需要的书。 2、最后一步我必然会在7种购买方案中选择一种,因此我要在7种购买方案中选择一个最佳情况。 3、子问题是,我选择了某个方案后,如何使得购买剩余的书能用最少的钱?并且这个选择不会使得剩余的书为负数 。母问题和子问题都是给定三卷书的购买量,求最少需要用的钱,所以有"子问题重叠",问题中三个购买量设置为参数, 分别为i、j、k。 4、的确符合。 5、边界是一次购买就可以买完所有的书,处理方式请读者自己考虑。 6、每次选择最多有7种方案,并且不会同时实施其中多种,因此方案的选择互不影响,所以有"子问题独立"。 7、我可以用minMoney[i][j][k]来保存购买第1卷i本,第2卷j本,第3卷k本时所需的最少金钱。 8、共有x * y * z个问题,每个问题面对7种选择,时间为:O( x * y * z * 7) = O( x * y* z )。 9、用函数MinMoney(i,j,k)来表示购买第1卷i本,第2卷j本,第3卷k本时所需的最少金钱,那么有: MinMoney(i,j,k)=min(s1,s2,s3,s4,s5,s6,s7),其中s1,s2,s3,s4,s5,s6,s7分别为对应的7种方案使用的最少金钱: s1 = 60 * 0.95 + MinMoney(i-1,j,k) s2 = 60 * 0.95 + MinMoney(i,j-1,k) s3 = 60 * 0.95 + MinMoney(i,j,k-1) s4 = (60 + 60) * 0.9 + MinMoney(i-1,j-1,k) s5 = (60 + 60) * 0.9 + MinMoney(i-1,j,k-1) s6 = (60 + 60) * 0.9 + MinMoney(i-1,j,k-1) s7 = (60 + 60 + 60) * 0.85 + MinMoney(i-1,j-1,k-1)
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值