算法 - 动态规划 - 状态转移+01背包问题

本文探讨了如何使用动态规划解决01背包问题,通过分析拼多多C++岗笔试题中关于货物运输的问题,指出贪心算法的局限性,并详细解释了基于POJ 2923(Relocation)问题的动态规划解法,包括状态转移和二进制表示物品装载状态的方法。
摘要由CSDN通过智能技术生成

算法 - 动态规划 - 状态转移+01背包问题

在做拼多多C++岗的笔试题时候,第三题的题目是:

有N个货物(0<=N<=1024),每个货物的重量是W(100<=W<=300)。如果每辆车最多的载重为300,请问最少需要多少辆车才能运输所有货物。

开始尝试用贪心算法来求,先将货物从小到大排序,然后每次取最后最大的数装载,装不上时再取前面最小的数装载。这种贪心算法通过率为55%,原因是有些数据使用贪心算法行不通,比如:100 100 100 140 150 150 160。

后来自己下来思考这道题目,发现POJ的2923(Relocation)跟这道题大同小异:

有个人需要搬家,有N件物品,给个物品的重量是 w[i] 然后又两个车,每个车的载重量分别是C1和C2,求最少需要运输多少次才能把这些物品全部运输完毕。
输入输出:
Sample Input:
2 - - 例子个数
6 12 13 - - N个物品,第一辆车的容量v1,第二辆车的容量v2
3 9 13 3 10 11 - - N个物品的单个容量
7 1 100
1 2 33 50 50 67 98
Sample Output:
Scenario #1: - - 第一个例子
2 - - 两趟
Scenario #2: - - 第二个例子
3 - - 三趟

POJ的2923(Relocation)分析:
1. 用0 ~ 1 << N-1二进制表示物品是否装载的详细情况(即状态),其中0代表未装载,1代表装载。假设N为3,那么000表示没有装载,001表示第一件物品装载,011表示第一、二件物品装载,100表示第三件物品装载。
2. 用dp[i]表示状态i需要装载的最少次数,则此处动态规划方程为:dp[i|j] = min(dp[i|j], dp[i]+1)。其中要保证:a.i&j==0 b.j表示两趟车一次可运走的状态
3. 若(i&j == 0),表示:i状态与j状态没有重合的元素

POJ的2923(Relocation)代码:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

#define MAXVALUE 1<<30

bool isStateOK(int x, int v1, int v2, const vector<int> &vol)//判断一种状态是否可行(可以一次运走)
{
    int sum = 0;
    vector<bool> visit(v1+1, false);                         //vis[i]表示容量和为i的货物能否装上第一辆车
    visit[0] = true;

    for (int i = 0;i < vol.size();i++)
    {
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值