LeetCode 638. 大礼包(无限背包DP)

1. 题目

在LeetCode商店中, 有许多在售的物品。

然而,也有一些大礼包,每个大礼包以优惠的价格捆绑销售一组物品。

现给定每个物品的价格,每个大礼包包含物品的清单,以及待购物品清单。请输出确切完成待购清单的最低花费。

每个大礼包的由一个数组中的一组数据描述,最后一个数字代表大礼包的价格,其他数字分别表示内含的其他种类物品的数量。

任意大礼包可无限次购买。

示例 1:
输入: [2,5], [[3,0,5],[1,2,10]], [3,2]
输出: 14
解释: 
有A和B两种物品,价格分别为¥2和¥5。
大礼包1,你可以以¥5的价格购买3A和0B。
大礼包2, 你可以以¥10的价格购买1A和2B。
你需要购买3个A和2个B, 所以你付了¥10购买了1A和2B(大礼包2),以及¥4购买2A。示例 2:
输入: [2,3,4], [[1,1,0,4],[2,2,1,9]], [1,2,1]
输出: 11
解释: 
A,B,C的价格分别为¥2,¥3,¥4.
你可以用¥4购买1A和1B,也可以用¥9购买2A,2B和1C。
你需要买1A,2B和1C,所以你付了¥4买了1A和1B(大礼包1),以及¥3购买1B, ¥4购买1C。
你不可以购买超出待购清单的物品,尽管购买大礼包2更加便宜。说明:
最多6种物品, 100种大礼包。
每种物品,你最多只需要购买6个。
你不可以购买超出待购清单的物品,即使更便宜。

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/shopping-offers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题

2.1 状态压缩超时解

  • 思路是,把int看做买东西的个数的状态,3个位最大是7,题目说不超过6,物品也不超过6,最多18位就可以了
  • 一个int就可以存下买的物品的个数
  • 最后一个例子超时,可能这个最大的状态数太大了
class Solution {int n;
public:int shoppingOffers(vector<int>& price, vector<vector<int>>& special, vector<int>& needs) {n = price.size();int i, j, k, target = 0, num, newstate;for(i = 0; i < n; ++i)modify(target, i, needs[i]);vector<int> dp(target+1,INT_MAX);dp[0] = 0;//什么都不买bool lessNeed;for(i = 0; i <= target; i++){if(dp[i] == INT_MAX)continue;vector<int> count(n);for(j = 0; j < n; ++j)count[j] = getnum(i,j);for(j = 0; j < n; ++j){newstate = i;num = count[j]+1;//状态i下,第j个物品的个数,再买一件+1if(num > needs[j])continue;//超数量了modify(newstate, j, num);if(newstate <= target)dp[newstate] = min(dp[newstate],dp[i]+price[j]);}for(k = 0; k < special.size(); ++k){newstate = 0;lessNeed = true;for(j = 0; j < n; ++j){num = count[j]+special[k][j];//状态i下,第j个物品的个数+买大礼包的数量           if(num > needs[j]){lessNeed = false;break;}modify(newstate, j, num);}if(lessNeed && newstate <= target)dp[newstate] = min(dp[newstate],dp[i]+special[k][n]);}}return dp[target];}void modify(int& state, int i, int newnum){int bit = 3*i, k = 0, newnum_bit;for(k = 0; k < 3; ++k,++bit)state = (~(1<<bit))&(state);//清零3位组成的一个物品数量bit = 3*i;for(k = 0; k < 3; ++k,++bit){newnum_bit = (newnum>>k)&1;//if(newnum_bit)state |= (1<<bit);}}int getnum(int state, int i){int bit = 3*i+2, num = 0;for(int k = 0; k < 3; ++k,--bit)num = num*2+((state>>bit)&1);return num;}
};

2.2 6维动态规划

  • 把单个的也处理成大礼包,统一处理
  • 不满6个的都补满,方便处理
class Solution {
public:int shoppingOffers(vector<int>& price, vector<vector<int>>& special, vector<int>& needs) {int n = price.size();int i,j,a,b,c,d,e,f, money;for(i = 0; i < n; ++i){vector<int> bag(7,0);bag[i] = 1;bag[6] = price[i];special.push_back(bag);//单个物品,加入礼包}int dp[11][11][11][11][11][11];memset(dp,0x7f,sizeof(dp));//按字节赋值,1字节8位 0111 1111dp[0][0][0][0][0][0] = 0;vector<int> t(6,0);while(needs.size() < 6)needs.push_back(0);for(i = 0; i < needs.size(); ++i)t[i] = needs[i];for(vector<int> & s : special){vector<int> nd(6,0);money = s.back();for(j = 0; j < s.size()-1; ++j)nd[j] = s[j];for(a = 0; a <= t[0]; ++a)for(b = 0; b <= t[1]; ++b)for(c = 0; c <= t[2]; ++c)for(d = 0; d <= t[3]; ++d)for(e = 0; e <= t[4]; ++e)for(f = 0; f <= t[5]; ++f){if(dp[a][b][c][d][e][f] != 0x7f7f7f7f && a+nd[0] <= needs[0]&& b+nd[1] <= needs[1] && c+nd[2] <= needs[2]&& d+nd[3] <= needs[3] && e+nd[4] <= needs[4]&& f+nd[5] <= needs[5])dp[a+nd[0]][b+nd[1]][c+nd[2]][d+nd[3]][e+nd[4]][f+nd[5]]= min(dp[a+nd[0]][b+nd[1]][c+nd[2]][d+nd[3]][e+nd[4]][f+nd[5]],dp[a][b][c][d][e][f]+money);}}return dp[t[0]][t[1]][t[2]][t[3]][t[4]][t[5]];}	
};

280 ms 18.4 MB C++

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/475757.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在2008 server安装vm server时发生的错误error1718、error1335……

;转载于:https://www.cnblogs.com/minglog/archive/2011/02/15/1955290.html

keepass2Android密码,Keepass2Android密码管理(快速解锁密码)

Keepass2Android密码管理能帮助我们保存各类网站、应用的密码&#xff0c;大家提前设置好之后每次输入密码的时候只需要输入很少的字符就能快速解锁密码&#xff0c;为大家的日常使用提供方便。软件特色* 几乎可与所有的Android 的浏览器结合使用 (见下文)*快速解锁&#xff1a…

LeetCode 845. 数组中的最长山脉(中心扩展)

1. 题目 我们把数组 A 中符合下列属性的任意连续子数组 B 称为 “山脉”&#xff1a; B.length > 3存在 0 < i < B.length - 1 使得 B[0] < B[1] < ... B[i-1] < B[i] > B[i1] > ... > B[B.length - 1] &#xff08;注意&#xff1a;B 可以是 A 的…

hibernate3.6.0日志配置

hibernate3 自带的默认的日志框架是slf4j&#xff0c;hibernate3的slf只是一个日志的接口&#xff0c;而hibernate3 自带默认的日志框架&#xff0c;在实际开发中很少有公司或者是项目中用到&#xff0c;这里记录一种使用log4j的日志框架来代替slf4j日志框架的实现&#xff0c;…

android stackview,Android StackView 使用示例

cell.xml 布局文件&#xff1a;xmlns:android"http://schemas.android.com/apk/res/android"android:id"id/cellImage"android:layout_width"200dp"android:layout_height"200dp"/>主布局文件&#xff1a;android:id"id/activ…

LeetCode 1239. 串联字符串的最大长度(回溯/动态规划)

文章目录1. 题目2. 解题2.1 回溯超时解2.2 回溯优化2.3 动态规划1. 题目 给定一个字符串数组 arr&#xff0c;字符串 s 是将 arr 某一子序列字符串连接所得的字符串&#xff0c;如果 s 中的每一个字符都只出现过一次&#xff0c;那么它就是一个可行解。 请返回所有可行解 s 中…

android 伪造gps位置,在Android中使用GPS的假位置

您正在开发一个将设置坐标(经度和纬度)的应用程序.它必须显示我的位置,因为我在那个坐标.它类似于位置欺骗者.. http://www.androidzoom.com/android_applications/tools/location-spoofer_gkmc.html但我没有这样做..这是我的代码..请任何人帮助我.public class Mock extends M…

LeetCode 395. 至少有K个重复字符的最长子串(分治)

1. 题目 找到给定字符串&#xff08;由小写字符组成&#xff09;中的最长子串 T &#xff0c; 要求 T 中的每一字符出现次数都不少于 k 。输出 T 的长度。 示例 1: 输入: s "aaabb", k 3 输出: 3 最长子串为 "aaa" &#xff0c;其中 a 重复了 3 次。示…

WCF 体系结构图

转载于:https://www.cnblogs.com/agressivo/articles/1958858.html

android studio电影院选座,8排电影院选座最佳位置

8排电影院选座最佳位置在哪里呢&#xff1f;8排电影院属于小影厅&#xff0c;小影厅银幕宽度在10米以下&#xff0c;座位100以内&#xff0c;座位排数通常拥有8-14排&#xff0c;小影厅整体空间小&#xff0c;选座时要选中间稍靠后一些的位置。由于整体排数少&#xff0c;因此选…

LeetCode 1011. 在 D 天内送达包裹的能力(二分查找)

1. 题目 传送带上的包裹必须在 D 天内从一个港口运送到另一个港口。 传送带上的第 i 个包裹的重量为 weights[i]。每一天&#xff0c;我们都会按给出重量的顺序往传送带上装载包裹。我们装载的重量不会超过船的最大运载重量。 返回能在 D 天内将传送带上的所有包裹送达的船的…

仿Jquery链式操作的xml操作类

经常需要对xml文件进行操作&#xff0c;参考了Jquery的链式操作后实现了xmlHelper类。代码usingSystem;usingSystem.Data;usingSystem.Configuration;usingSystem.Xml;namespaceConfigUpdate{ ///<summary>///调用非静态的操作方法的 ///</summary>publiccla…

4月17日鸿蒙开发者大会,4月17日这天,将载入华为史册

文/笨鸟原创不易&#xff0c;禁止抄袭、洗稿&#xff0c;违者必究&#xff01;万众瞩目的华为鸿蒙系统对于国人来说&#xff0c;一部智能手机只有实现了芯片和系统技术的自主化&#xff0c;才能被称之为真正的国产手机。而就目前的国内手机市场而言&#xff0c;除华为之外的所有…

LeetCode 875. 爱吃香蕉的珂珂(二分查找)

1. 题目 珂珂喜欢吃香蕉。这里有 N 堆香蕉&#xff0c;第 i 堆中有 piles[i] 根香蕉。警卫已经离开了&#xff0c;将在 H 小时后回来。 珂珂可以决定她吃香蕉的速度 K &#xff08;单位&#xff1a;根/小时&#xff09;。每个小时&#xff0c;她将会选择一堆香蕉&#xff0c;…

MsSql正反表达式

例子&#xff1a; UPDATE [Photo_Table] SET istopistop^1,IsTopDateTimegetdate() WHERE charindex(, rtrim(PHOTOID) , , , PHOTOIDLIST ,)>0转载于:https://www.cnblogs.com/yibinboy/archive/2011/02/22/1961675.html

LeetCode 1455. 检查单词是否为句中其他单词的前缀

1. 题目 给你一个字符串 sentence 作为句子并指定检索词为 searchWord &#xff0c;其中句子由若干用 单个空格 分隔的单词组成。 请你检查检索词 searchWord 是否为句子 sentence 中任意单词的前缀。 如果 searchWord 是某一个单词的前缀&#xff0c;则返回句子 sentence 中…

html怎么修改锚点的属性,在HTML中设置自定义锚点

我已经在帖子here和here中看到了这个话题,但它们并没有真正帮助我.情况非常相似&#xff1a;页面顶部的滚动页面和粘性菜单栏(固定div),锚点分散在长滚动文本中.像这样的HTML&#xff1a;Heading Foothis is some text, and a lot of it...jump to Heading Foo...Heading Blaan…

PHP输出Excel实例代码

这里使用PHPExcel的开源类 一个完整的实例&#xff1a; <?php require_once("../includes/function.php"); //提供了SQL注入检测函数inject_check require_once("../class/DB.php"); //DB操作类&#xff0c;自己扩展一下 $db new DB(); if($_GET[sho…

LeetCode 1456. 定长子串中元音的最大数目(滑动窗口)

1. 题目 给你字符串 s 和整数 k 。 请返回字符串 s 中长度为 k 的单个子字符串中可能包含的最大元音字母数。 英文中的 元音字母 为&#xff08;a, e, i, o, u&#xff09;。 示例 1&#xff1a; 输入&#xff1a;s "abciiidef", k 3 输出&#xff1a;3 解释&a…

Xml文档添加节点和属性

在实际的应用开发中需要我们对xml进行添加节点和属性&#xff0c;动态的去完成&#xff0c;在这之前&#xff0c;先看看XmlNode和XmlElement之间的关系 1、XmlElement继承XmlLinkedNode又继承XmlNode&#xff0c;所以XmlElement是XmlNode的子集&#xff0c;那么从继承的关系来说…