10
1 1 1 5 5 7 9 //体积
5 5 1 5 3 5 1//价值
 

01
完全
多重
分组
有依赖性
...
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
01背包


vi ci

if (i+vi)

n 为物品数,m为背包容量

f[i][j]//表示在体积为j的情况下,装前i个物品时的最大价值。
那么在f[i-1][j]//取前i-1个物品的最大价值上考虑是否能放下第i的物品。

对于每一个物品,我们有两种选择,①是取,f[i][j]=f[i-1][j-v[i]]+c[i],②是不取
f[i][j]=f[i-1][j],
综上所述,f[i][j]=max(f[i-1][j],f[i-1][j-v[i]]+c[i]);
     
 
for (int i=1;i<=n;i++)
   for (int
j=m;j>0;j--)//思考,为什么是倒叙循环?
      if
(j>=v[i]) f[i][j]=max(f[i-1][j],f[i-1][j-v[i]]+c[i]);
   
  
     
     
    else f[i][j]=f[i-1][j];
f[n][m]即为最优解。 

优化 :① 用滚动数组来求。
     
 ② 用一维优化。//观察动态规划方程,我们不难发现,f[i][j]只与上一层有关。
for (int i=1,i<=n;i++)
   for (int j=v;j;j--)
     
 f[j]=max(f[j];f[j-v[i]]+c[i]); 

http://codevs.cn/problem/1068/
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
完全背包


vi ci

与01背包最大的区别 对于每一个物品来说,可以选无数次。

解答上次思考:
 if 1->n
   if vi==4,
 ci==4
     
f[4]==4; f[8]==f[4]+4;
   也就是说 1->n,
对于一个物品,不止选一次。
也就是 完全背包。
  for (int i=1;i<=n;i++)
    for (int
j=1;j<=m;j++)//思考,为什么是倒叙循环?
      if
(j>=v[i]) f[i][j]=max(f[i-1][j],f[i-1][j-v[i]]+c[i]);
   
  
     
     
    else f[i][j]=f[i-1][j];
同样 优化也有两种
   ① 用滚动数组来求。
   ② 用一维优化。
   for (int
i=1;i<=n;i++)
     
 for (int j=1;j<=m;j++)
     
   
 f[j]=max(f[j],f[j-v[i]]+c[i]);
http://acm.nyist.net/JudgeOnline/problem.php?pid=311
 
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
多重背包


也就是说限定物品选择的个数。

vi ci ki //对于第i个物品,体积为vi,价值ci,只能选择ki次。

① 将 ki 分为 ki 个物品,然后用01背包解决。
   代码:
      for
(int i=1;i<=n;i++)
     
   {
     
     
scanf("%d%d%d",&v,&c,&k);
     
     
 for (int j=1;j<=k;j++)
     
     
   
 s[++cnt].v=v,s[cnt].c=c;
     
    }
② 采用类似lca的方法,将k个物品分为 1,2,4,8,16,..... 2^n.
 
 这样对于每一个自然数i都可以被组合出来。然后再采用01背包。
   代码:
     
 while (n--)    
//接下来输入n中这个物品  
     
   {  
     
     
 scanf("%d%d%d", &vi, &ci, &ki);
 //输入每种物品的数目和价值  
     
     
 for (int k=1; k<=ki; k<<=1)
  //<<右移 相当于乘二  
     
     
  {  
     
     
    value[cnt]=k*vi;//体积
 
     
     
    size[cnt++]=k*ci;//价值
 
     
     
    ki-=k;
 
     
     
  }  
     
      if
(ki>0)  
     
     
  {  
     
     
    value[cnt]=ki*vi;
 
     
     
    size[cnt++]=ki*ci;
 
     
     
  }  
     
   }
http://codevs.cn/problem/3269/
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
分组背包


  vi ci ki
//对于i的物品,体积为vi,价值为ci,属于第ki个分组,对于每一个分组而言,最多选一件。
  for k=1->K
     for
j=M->0    
  
     
   for
i=1->s[k]//当前分组中的所有元素
     
     
 f[j]=max(f[j],f[j-v[i]]+v[i]); 
  ps:注意三层循环的顺序,for j=m->0 必须在 for
i=1->s[k] 之外,这样才能保证每一个分组最多只会选1个物品。
http://acm.hdu.edu.cn/showproblem.php?pid=1712
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
有依赖性背包


直接上例题 

http://codevs.cn/problem/1155/
预处理分组,然后上分组背包。
说实话,这种题不难,但预处理很恶心。
   begin
   
 read(m,n);
   
 j:=0;
     for
i:=1 to n do
     
 begin
     
   read(x1,y1,z1);
     
   if z1=0 then begin inc(j);
inc(s[j,0].x); s[j,s[j,0].x].x:=x1; s[j,s[j,0].x].y:=x1*y1;
s[j,0].y:=i; end
     
     
     else
     
     
     
 begin
     
     
     
   for k:=1 to j do
     
     
     
     if
z1=s[k,0].y then
     
     
     
     
 begin
     
     
     
     
  z:=s[k,0].x;
     
     
     
     
 for l:=1 to z do
     
     
     
     
    begin
     
     
     
     
   
 inc(s[k,0].x);
     
     
     
     
   
 s[k,s[k,0].x].x:=s[k,l].x+x1;
     
     
     
     
   
 s[k,s[k,0].x].y:=s[k,l].y+x1*y1;
     
     
     
     
    end;
     
     
     
     
 end;
     
     
     
 end;
     
 end;
     
s[0,0].x:=j;
   end;

--------------------------------------------------------------------------------------------------------------------------------------------------------------------
背包问题的扩展
     
     
     
     
     
     
     
     
     
     
     
     
  多米诺骨牌
     
多米诺骨牌有上下2个方块组成,每个方块中有1~6个点。现有排成行的
上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|。例如在图8-1中,S1=6+1+1+1=9,S2=1+5+3+2=11,|S1-S2|=2。每个多米诺骨牌可以旋转180°,使得上下两个方块互换位置。
编程用最少的旋转次数使多米诺骨牌上下2行点数之差达到最小。

对于图中的例子,只要将最后一个多米诺骨牌旋转180°,可使上下2行点数之差为0。
 输入输出格式 Input/output
输入格式:
输入文件的第一行是一个正整数n(1≤n≤1000),表示多米诺骨牌数。接下来的n行表示n个多米诺骨牌的点数。每行有两个用空格隔开的正整数,表示多米诺骨牌上下方块中的点数a和b,且1≤a,b≤6。
输出格式:
输出文件仅一行,包含一个整数。表示求得的最小旋转次数。 
题解 :
   
f[i][j]//表示前i个骨牌,点数相差j的翻动次数。
    动态转移方程:
    int cha=a[i]-c[i];
    for i=2->n
     
 for j=-5000->5000  
     
   
f[i][j]=min(f[i][j],min(f[i-1][j-a[i]],f[i-1][j+a[i]]+1));
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
   

hyxzc_背包九讲课件的更多相关文章

  1. 【DP_背包专题】 背包九讲

    这段时间看了<背包九讲>,在HUST VJUDGE上找到了一个题单,挑选了其中16道题集中做了下,选题全部是HDU上的题,大多是简单题.目前做了点小总结,大概提了下每道题的思路重点部分,希 ...

  2. 背包九讲PDF

    本资料仅限个人学习交流使用,不得用于商业用途. 背包九讲PDF:https://pan.baidu.com/s/17rTxMwCo9iSTOW77yucdXQ   提取码:xbqa

  3. My背包九讲——概述

    文章目录 什么是背包问题 背包问题的分类 [第一讲 01背包问题](https://blog.csdn.net/qq_34261446/article/details/103705068) 第二讲 完 ...

  4. 背包九讲 && 题目

    ★.背包求方案数的时候,多重背包是不行的,因为产生重复的背包会有多种情况. ★.背包记录路径的时候,其实是不行的,因为更新了12的最优解,如果它依赖于6这个背包,然后你后面改变了6这个背包,就GG 1 ...

  5. dd大牛的《背包九讲》

    P01: 01背包问题 题目 有N件物品和一个容量为V的背包.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 基本思路 这是最 ...

  6. 直接抱过来dd大牛的《背包九讲》来做笔记

    P01: 01背包问题 题目 有N件物品和一个容量为V的背包.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 基本思路 这是最 ...

  7. 摘自 dd大牛的《背包九讲》

    P01: 01背包问题 题目 有N件物品和一个容量为V的背包.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 基本思路 这是最 ...

  8. 背包九讲(Orz)

    P01: 01背包问题 题目 有\(N\)件物品和一个容量为\(V\)的背包.第\(i\)件物品的费用是\(c[i]\),价值是\(w[i]\).求解将哪些物品装入背包可使这些物品的费用总和不超过背包 ...

  9. dd 在度娘上看到的一个大牛的《背包九讲》 (:

    P01: 01背包问题 题目 有N件物品和一个容量为V的背包.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 基本思路 这是最 ...

随机推荐

  1. Eclipse来push,fetch,rebase代码

    如何与项目里的其他人一起合作项目,提交代码并更新呢?这里提出我比最近用到的两种工具:一种是Eclipse,另外一个是SourceTree.个人推荐从事Java开发的话,可以用Eclipse.当然,还有 ...

  2. The base command for the Docker CLI.

    Description The base command for the Docker CLI. Child commands Command Description docker attach At ...

  3. Spring MVC 参数校验

    转自:http://blog.csdn.net/eson_15/article/details/51725470 这一篇博文主要总结一下springmvc中对数据的校验.在实际中,通常使用较多是前端的 ...

  4. js错误处理

    导致程序无法继续执行的异常状态称为错误. js中一旦发生错误,就会自动创建一个Error类型对象 js中有6中错误类型: SyntaxError 语法错误 ReferenceError 引用错误,找不 ...

  5. 【BZOJ2227】【ZJOI2011】看电影 [组合数][质因数分解]

    看电影 Time Limit: 10 Sec  Memory Limit: 259 MB[Submit][Status][Discuss] Description 到了难得的假期,小白班上组织大家去看 ...

  6. 2017年上海金马五校程序设计竞赛:Problem C : Count the Number (模拟)

    Description Given n numbers, your task is to insert '+' or '-' in front of each number to construct ...

  7. 【Python实例一】使用minidom读取xml文件

    前言:最近刚在廖雪峰老师的网站里学习了Python的基础内容,想着循序渐进地找点实例练练手,网上看到有很多相关资料,决定针对感兴趣的内容实际编码实践一下,昨天刚好看到有关使用Python来读取XML文 ...

  8. 无线路由器中WMM/Short GI/AP隔离各是什么功能, 开启时PC无法ping通手机.

      无线路由器的WMM功能和开启ap隔离,以及开启ShortGI有什么用 无线路由器中有开启WMM.开启Short GI和开启AP隔离分别代表什么呢?这是我在我的TP-LINK无线路由器TL-WR84 ...

  9. CentOS RabbitMQ安装

    1. 安装erlang,参考另外一篇文章: http://www.cnblogs.com/wanpengcoder/p/5287302.html 2. 安装libxslt和: yum install ...

  10. python学记笔记 2 异步IO

    在IO编程中,我们知道CPU的速度远远快于磁盘,网络IO,在一个线程中,CPU执行速度的代码非常快,然而遇到IO操作就需要阻塞 需要等待IO操作完成才能继续下一步的动作.这种情况叫做同步IO 在IO操 ...