【完全背包】A005_LC_贴纸拼词(dp + 状态压缩)
我们给出了 N 种不同类型的贴纸。每个贴纸上都有一个小写的英文单词。
你希望从自己的贴纸集合中裁剪单个字母并重新排列它们,从而拼写出给定的目标字符串 target。
如果你愿意的话,你可以不止一次地使用每一张贴纸,而且每一张贴纸的数量都是无限的。
拼出目标 target 所需的最小贴纸数量是多少?如果任务不可能,则返回 -1。
示例 1:
输入:
["with", "example", "science"], "thehat"
输出:
3解释:
我们可以使用 2 个 "with" 贴纸,和 1 个 "example" 贴纸。
把贴纸上的字母剪下来并重新排列后,就可以形成目标 “thehat“ 了。
此外,这是形成目标字符串所需的最小贴纸数量。示例 2:
输入:
["notice", "possible"], "basicbasic"
输出:
-1解释:
我们不能通过剪切给定贴纸的字母来形成目标“basicbasic”。
提示:
stickers 长度范围是 [1, 50]。
stickers 由小写英文单词组成(不带撇号)。
target 的长度在 [1, 15] 范围内,由小写字母组成。
在所有的测试案例中,所有的单词都是从 1000 个最常见的美国英语单词中随机选取的,目标是两个随机单词的串联。
时间限制可能比平时更具挑战性。预计 50 个贴纸的测试案例平均可在35ms内解决。
方法一:背包 + 状压
第一眼锁定是背包,比较南翔的是如果状态表示,但观察到 target 的长度只有 15,嗯,嘻嘻,状压安排了…
思路
假设 m = target.size(),cap = 1<<m
- 定义状态:
- f[i] 表示匹配状态为 i 时的最少贴纸数
- 思考初始化:
- f[0] = 0,f[1…cap] = -1
- 思考状态转移方程:
- f[j] = min(f[j], f[i] + 1)
- j 时用拼接贴纸状态 i 的基础上再加入新贴纸 s 的贡献后的状态;
- k 是 target 的第 k 位字符,
- f[j] = min(f[j], f[i] + 1)
- 思考输出:f[cap-1]
class Solution {public:int minStickers(vector<string>& ss, string& tar) {int m=tar.size(), cap=1<<m, f[cap];memset(f, -1, sizeof f); f[0]=0;for (string& s : ss) for (int i=0; i<cap; i++) if (f[i]!=-1) {int j=i;for (char c : s) //获取s的贡献for (int k=0; k<m; k++) {if (c==tar[k] && (j&(1<<k)) == 0) {j |= 1<<k;break;}}if (f[j] == -1) f[j]=f[i]+1;else f[j]=min(f[j], f[i]+1);}return f[cap-1];}
};
复杂度分析
- 时间复杂度:O(2m×n×m)O(2^m × n × m)O(2m×n×m),
- 空间复杂度:O(2m)O(2^m)O(2m)
【完全背包】A005_LC_贴纸拼词(dp + 状态压缩)相关推荐
- Leetcode 691. 贴纸拼词 C++
Leetcode 691. 贴纸拼词 题目 我们给出了 N 种不同类型的贴纸.每个贴纸上都有一个小写的英文单词. 你希望从自己的贴纸集合中裁剪单个字母并重新排列它们,从而拼写出给定的目标字符串 tar ...
- 【LeetCode】 贴纸拼词(动态规划)
691. 贴纸拼词 - 力扣(LeetCode) 一.题目 我们有 n 种不同的贴纸.每个贴纸上都有一个小写的英文单词. 您想要拼写出给定的字符串 target ,方法是从收集的贴纸中切割单个字母并重 ...
- 贴纸拼词--动态规划
贴纸拼词 我们有 n 种不同的贴纸.每个贴纸上都有一个小写的英文单词. 您想要拼写出给定的字符串 target ,方法是从收集的贴纸中切割单个字母并重新排列它们.如果你愿意,你可以多次使用每个贴纸,每 ...
- java编程贴纸问题_Java实现 LeetCode 691 贴纸拼词(DFS+map记录)
691. 贴纸拼词 我们给出了 N 种不同类型的贴纸.每个贴纸上都有一个小写的英文单词. 你希望从自己的贴纸集合中裁剪单个字母并重新排列它们,从而拼写出给定的目标字符串 target. 如果你愿意的话 ...
- CCF201409-5 拼图(100分)【插头DP+状态压缩】
试题编号: 201409-5 试题名称: 拼图 时间限制: 3.0s 内存限制: 256.0MB 问题描述: 问题描述 给出一个n×m的方格图,现在要用如下L型的积木拼到这个图中,使得方格图正好被拼满 ...
- DP——状态压缩dp
状态压缩DP 蒙德里安的梦想 分析题目,当我们先摆横着放的方块,再摆放竖着放的方块,当横着放的小方块摆放完后,竖着放的方块也就确定了,因此总方案数应该等于只放横着的小方块的合法方案数.我们考虑每一列可 ...
- 【力扣每日一题】691. 贴纸拼词
题目描述 我们有 n 种不同的贴纸.每个贴纸上都有一个小写的英文单词. 您想要拼写出给定的字符串 target ,方法是从收集的贴纸中切割单个字母并重新排列它们.如果你愿意,你可以多次使用每个贴纸,每 ...
- 动态规划——贴纸拼词
/* 题目二 给定一个字符串str,给定一个字符串类型的数组arr arr里的每一个字符串,代表一张贴纸,你可以把单个字符剪开使用,目的是拼出str来 每一种贴纸都可以使用任意张,重复的算2张,每一张 ...
- 暴力递归到动态规划 05 (贴纸拼词)
题目链接 1. 暴力递归(超时) public int minStickers(String[] stickers, String target) {int result = minSticker(s ...
最新文章
- 正则表达式用户名密码电话身份证Email使用
- 观察者模式C#实现实例(一)
- vue.js源码学习分享(一)
- java 压缩汉字字节_java中计算汉字的字节数
- 软件工程专插本_2021年专插本部分招生专业(拟),广科/广东理工/华商/培正/松田/工商大!...
- SSD300网络结构(pytorch)+多尺度训练与测试
- c语言 多文件 学生系统,编的学生成绩管理系统 从文件中读取保存数据总会多读入一组乱码数据...
- 给网站添加灰白滤镜(默哀主题色)
- android定时器课程设计,定时器课程设计.doc
- LeetCode(1002)——查找常用字符(JavaScript)
- Caused by: org.apache.ibatis.ognl.OgnlException: source is null for getProperty(null, mil_id)
- 实现带有拉普拉斯修正的朴素贝叶斯_数据科学 | 算法工程师必备的机器学习贝叶斯分类器...
- 网络编程:TCP简单实现群聊功能
- php的gc回收机制,php垃圾回收机制相关(GC)
- 罗马数字转换器|罗马数字生成器
- canvas制作圆角矩形(包括填充矩形的功能)
- ASM、AAM算法介绍
- 【JVM】 TLAB到底是干什么的
- 初三英语关于计算机的作文,关于介绍电脑的英语作文初三80词左右急
- 漏洞复现之ms10_018