总结: 0-1背包问题 --> 动态规划d…
2016-05-19 23:15
501 查看
动态规划
(参照刘汝佳代码)
1.
有n种物品,每种只有一个.第i种物品的体积是Vi , 重量为Wj , 选一些物品装到一个容量为C的背包,
使得背包里面的物品不超过总体积C的前提下重量尽可能的大.
1<=n<=100,
1<=Vi<=C<=10000,1<=Wi<=10^6
解法1:
状态方程: d(i,j) = max( d(i+1,j) , d(i+1,j-v[i]) +
w[j] ); (i > n 时,d(i,j) =
0.)
d(i,j)表示 当前第i层,背包剩余容量为j时接下来的最大重量和.
代码: d[1][c]为结果
for(int i = n; i >= 1;
--i)
{
for(int j = 0; j <= c;
++j)
{
d[i][j] = (i == n ? 0 : d[i+1][j]);
if(j >= v[i])
{
if(d[i][j] <=
d[i+1][j-v[i]]+w[i])
d[i][j] = d[i+1][j-v[i]]+w[i];
}
}
}
解法2: 相反的规划方向.
采用对称的状态. 设f(i,j)
表示把前i个物品装到容量为j的最大总重量.
状态方程: f(i,j) = max( f(i-1,j) ,
f(i-1,j-v[i])+w[i] );
i == 0 时为0 , j < 0时负无穷.
结果为f(n,c);
代码:
for(int i =1 ; i <= n;
++i)
{
for(int j = 0; j <= c;
++j)
{
f[i][j] = (i == 1 ? 0 : f[i-1][j]);
if(j >= v[i])
{
if(f[i][j] <=
f[i-1][j-v[i]]+w[i])
f[i][j] = f[i-1][j-v[i]]+w[i];
}
}
}
总结: 尽管在很多情况下,记忆化(剪枝)搜索程序直观,易懂. 但是计算顺序如果变得重要时
明显是递推时比较方便.效率相应高些. 同时规划的方向也是不唯一的看个人思维方向.
相关文章推荐
- 图论: 并查集 + kruskal 求最小…
- 图论: 经典的邻接矩阵 + dijkstra …
- 图论: 优先队列 + dijkstra最短路…
- 图论: 邻接表 + STL优先队列 + dij…
- 图论: Bellman_ford + 队列 + 邻接…
- 图论: bellman_ford 求单源最短路…
- 图论: spfa == Shortest Path Fast…
- 图论: 匈牙利算法 Edmonds
- STL: map类的用法介绍1
- STL-Intelligent IME
- iOS app打包 -- 生成ipa测试包 步骤详解
- Linux : 线程(thread)
- Linux: 进程间通信
- Linux:网络编程 (上)
- Linux:网络编程 (下)
- Linux:内核进程 (脑里面必有…
- Linux:proc文件系统
- Linux:Qt的编译和安装配置 (本…
- Qt:亲手写框体 C++ GUI (没课的…
- Qt:快速设计对话框. C++ GUI