HDU 1114 Piggy-Bank

这个基本上还是01背包嘛,但是这回我把状态的判定条件设置为在一定重量的情况下,尽量让硬币的总价值更少。

HDU 2191 悼念512汶川大地震遇难同胞――珍惜现在,感恩生活

这个是一个多重背包问题,其实多重背包就是01背包,举个例子(其实是扒的):

¤像如果某件物品的重量为1,价值为2,数量为1000

¤我们就可以拆分成:

¤重量为1,价值为2的物品 重量为2,价值为4的物品

¤重量为4,价值为8的物品 …

¤重量为256,价值为512的物品

¤重量为489,价值为489*2的物品

简要地说,就是先拿二进制拆,拆出来1,2,4,8,16,32。。。这样的,等到拆不动了(剩下的不够下一个2进制整幂了),就把剩下的单独拿出来当成一个新物品,这样就不会丢解了。拆分完之后不就变成01背包了嘛。

HDU 2546 饭卡

这道题给我玩惨了,原因就是“hehe”那里没有加,后果是啥大家都知道。。。

其实是一个包装过了的01背包问题,既然>=5块时都能随便花,那么我就把最贵的那个留下,然后尽量把饭卡刷到还剩5块钱的程度(不一定是五块,但尽量靠近五块),然后再去买那个最贵的,一次性刷爆。(虽然还是有可能刷不爆的,但余额尽量小是真的),“尽量把饭卡刷到还剩5块钱的程度”,这个就可以转化为重量限定m-5,每个物品重量与价值相等情况下的01背包问题。

就这样。

POJ 3624 Charm Bracelet 顺便讲一下01背包

裸的01背包问题,是DP的基础题型了,没有太多好说的。

简要说一下01背包问题的状态转移特点:按两个基准纪录数据,第一个基准是我们从0~a号物品中选,第二个基准是选择的物品已经有了多少重量b,这样组成了dp数组dp[a][b],这个数组存储的是当前状态的价值是多少。接下来我们开始dp,对于每一个当前状态(最多选择到第n个物品,已经占用了w重量),我们是从两种先前状态中导出的:1.最多选择到n-1个物品(就是当前物品还没有考虑呢),占用重量w-x(x是第n个物品重量),在这个状态上,我们添加上第n个物品。2.最多选择到n-1个物品,占用重量w,在这个状态上,我们什么也不做,直接把他当成当前状态。

在这两种先前状态中选择最好的那个(有时候因为某些原因,只能选择一个,那就选唯一的那个就好),保存下来决定为当前状态,再供以后使用。

这样我们只要读取dp[i][j]的值,就是“选择1~i中的物品,重量限定为j,最高价值是?”这个问题的答案。(没有用滚动数组的话)

Scroll to top