2018/10/9美团笔试编程第一题(Android)
题意大概是:输入n表示有n份菜,输入X表示优惠券满X减10,接下来n个数表示每份菜的价格,每份菜最多点一份。求使用优惠券的最少金额。
这是一道很有意思的题目,其实0-1背包问题的变体,关于0-1背包问题,我也只懂回溯法和动态规划。在此再复习一下。
背包问题:背包最大可装物品重量总共为w,每件物品为w[i],价值为v[i],求容量内可装最大价值。
动态规划
设 dp[i][j]
表示在考虑到了第i件商品,背包最大容量为j时,可获得的最大价值。
状态传递方程为 dp[i][j] = dp[i-1][j]
,此时是 w[i] > j
,表明背包装不下该物品。当装得下时,则要考虑装入与不装入哪一种更具有价值,传递方程为 dp[i][j] = max(dp[i-1][j],dp[i-1][j-w[i]]+v[i])
。以上
回溯法
回溯法采用递归搜索dfs
,当搜到满足要求的点时更新当前的value
,然后剪枝返回,不需要往下搜(甚至可以利用剪枝函数再次优化)。当搜到底时,说明搜不到要求的解,失败了返回。
题目变形
上面的编程题可以看成在菜品总价减去优惠券得到差价,求不超过差价的前提下尽可能多的装入菜