码迷,mamicode.com
首页 > 编程语言 > 详细

基础算法(七)——动态规划【0/1背包问题】

时间:2017-11-07 00:17:04      阅读:215      评论:0      收藏:0      [点我收藏+]

标签:ima   function   size   介绍   nbsp   状态   new   暴力   比较   

  首先,对于动态规划,我来做一个简短的介绍,相信各位都看得懂。动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法。先给一道最简单的例题(小学奥数水平):

技术分享

 

技术分享

这就是一个模拟的动态规划法!

 

 

好了,现在开始认识一下最简单的动态规划实例:0/1背包

【问题描述】有一位旅行者要出远门,到商店里去筹备东西。在商店里,摆放了n样物品,每种物品有各自的体积,但是每种物品只有一件。这个旅行家有一个限制装V个体积的物品的背包,但是这个旅行家比较有钱,想买贵的东西。请编程求出:将哪些物品装入背包可使这些物品的费用总和不超过背包体积V,且价值总和最大。

乍一看到,感觉直接模拟暴力即可。但是,当数据量非常大的时候,这种方法就不显得十分的管用了。于是,我们打算用多的空间来换时间。

设数组dp[i,j]表示前i种物品装在体积为j的背包里所能获得的最大价值。存每件物品体积的数组为c,价值的数组为w

那么可以列出一个状态转移方程为:dp[i,j]:=max{dp[i-1,j],dp[i-1,v-c[i]+w[i]}。

所以稍作枚举即可。其实有点类似于记忆化搜索。

【参考程序】

 1 var
 2   c,p:  array[1..1000] of longint;
 3   i,j:  longint;
 4   f:    array[1..1000,1..1000] of longint;
 5   n,m,x:longint;
 6 Function max(a,b:integer):longint;
 7 begin
 8   if a>b then max:=a 
 9     else max:=b;
10 end;
11 
12 BEGIN
13   readln(n,m);
14   for i:=1 to n do
15   readln(c[i],p[i]);
16   for i:=1 to n do
17     for j:=1 to m do
18       if j>=c[i] then f[i,j]:=max(f[i-1,j],f[i-1,j-c[i]]+p[i])
19         else  f[i,j]:=f[i-1,j];
20   writeln(f[n,m]);
21 END.

其实,在空间上还是可以进一步优化的,如下:注意第二次循环是downto

 1 var a:array[0..100000]of longint;
 2 v,p,w,c:array[0..100]of longint;
 3 n,m,i,j:longint;
 4 begin
 5   readln(m,n);{m代表可供选择的物品数量,n包的体积}
 6   for i:=1 to m do
 7     read(v[i],w[i]); {v[i],w[i]分别代表第i件物品的体积和价值}
 8   for i:=1 to m do
 9   for j:=n downto v[i] do {从放入第一件物品到第i件物品时体积的变化}
10     if a[j]<a[j-v[i]]+w[i] 
11       then a[j]:=a[j-v[i]]+w[i];{比较放入j-1件物品和放入j件物品时价值谁大}
12    writeln(a[n]);
13 end.

 

基础算法(七)——动态规划【0/1背包问题】

标签:ima   function   size   介绍   nbsp   状态   new   暴力   比较   

原文地址:http://www.cnblogs.com/LJY2002/p/7795758.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!