01背包 ,完全背包,多重背包 dp (动态规划入门dp)
dp 动态规划,确实难啃, 光 最简单的 背包问题,就 费老大劲.
思想! 思想! 思想! 类似于递推, 局部找 关系.
背包问题, 就两种状态 放还是不放? 其实关于背包放不放的问题,如果用二进制思想来表示的话
很好理解, 0 代表不放 1 代表放; 那么对于现有的情况 假设有 n个物品 则 2进制则对应的长度应该为n 对于每一个物品用0 1 表示 000xx~~~111xx 数的大小几位pow(2,n);
for(i=0;i<pow(2,n);i++) { temp=i; for(j=0;j<n;j++) { if(temp%2)//放 执行语句 temp/=2; }
01背包 可以直接用二进制来表示,但是 当数据量 过大时 就会超时, 比较这是暴力.
01背包 的思想就是 对于这个物品,我要比较 我放进去的 价值大还是不放的价值大
转换成方程 f[i][v] = Max{f[i−1][v] ,f[i−1][v−wei[i]] + val[i]};前面就是 不放,后面 是放, 放进去后,背包的容量减少后的 + 放进去的价值=此时放进去的总价值, 二者比较!
转换成一维方程 逆序 逆序的目的是 保证后一个f[v]和f[v-we[i]]+val[i]是前一状态的
for(i=0;i<n;i++) for(j=c;j>=we[i];j--) //逆序! { dp[j]=max(dp[j],dp[j-we[i]]+val[i]); }
01 背包题目
HDU2546:饭卡
http://acm.hdu.edu.cn/showproblem.php?pid=2546
HDU1171:BigEvent in HDU
http://acm.hdu.edu.cn/showproblem.php?pid=1171
HDU2602:BoneCollector (模板题)
http://acm.hdu.edu.cn/showproblem.php?pid=2602
HDU2639:BoneCollector II(01背包第k优解)
http://acm.hdu.edu.cn/showproblem.php?pid=2639
HDU2955:Robberies
http://acm.hdu.edu.cn/showproblem.php?pid=2955
HDU3466:ProudMerchants
http://acm.hdu.edu.cn/showproblem.php?pid=3466
HDU1864:最大报销额
http://acm.hdu.edu.cn/showproblem.php?pid=1864
完全背包问题, 在01背包上, 将物品个数 改为无限个,此时二进制 思想 对于使用个数 就不好用了, 因为你可以用无数个,
此时 对于无限制时, 虽然可以在01 的基础上优化,将 价值小并且重量还大的 给优化掉, 这样的肯定不会选择.
但 极端问题,就难以解决.
同样 完全背包的转化
f[i][v]=Max{f[i-1][v-k*c[i]]+k*w[i]|0<=k*c[i]<=v}k的取值不同 f[][]的权值也发生改变 k可以去1,2,3,4,5,6 无数个
for i=1->>n; for j=0-->>V// 这里 变成正序 f[v]=max{f[v],f[v-c[i]]+w[i]}
正序 就保证了 我们对于每一个都有若干个可能来使用
/*,这正是为了保证每件物品只选一次,保证在 考虑“选入第i件物品”这件策略时,依据的是一个绝无已经选入第i件物品的子结果f[i-1][v-c[i]]。 而现在完全背包的特点恰是每种物品可选无限件,所以在考虑“加选一件第i种物品”这种策略 时,却正需要一个可能已选入第i种物品的子结果f[i][v-c[i]],所以就可以并且必须采用v=0..V的顺 序循环。这就是这个简单的程序为何成立的道理。 */ --> 大牛的 <背包九讲>
完全背包题目:
Hdu 1114:
http://acm.hdu.edu.cn/showproblem.php?pid=1114
Hdu 1248:
http://acm.hdu.edu.cn/showproblem.php?pid=1248
Hdu2159:
http://acm.hdu.edu.cn/showproblem.php?pid=2159
多重背包: 类似于母函数, 母函数 其实更好理解;
有N种物品和一个容量为V的背包。第i种物品最多有n[i]件可用,每件费用是c[i],价值 是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大
母函数的思想也是如此 给你 价值, 物品数量的限制, 然后凑,
f[i][v]=max{f[i-1][v-k*c[i]]+k*w[i]|0<=k<=n[i]}<<--限制条件.
把每n[i] 中的每个物品都当成一个独立的物品,而这 n[i] 个物品能够表示的重量其实用 log n[i]个组合后的物品就能表示。
多重背包
Hdu2191:
http://acm.hdu.edu.cn/showproblem.php?pid=2191
Hdu 2844:
http://acm.hdu.edu.cn/showproblem.php?pid=2844
Poj 1014
http://poj.org/problem?id=1014