P1278 单词游戏【题解】(状压dp)
单词游戏
题目描述
Io和Ao在玩一个单词游戏。
他们轮流说出一个仅包含元音字母的单词,并且后一个单词的第一个字母必须与前一个单词的最后一个字母一致。
游戏可以从任何一个单词开始。
任何单词禁止说两遍,游戏中只能使用给定词典中含有的单词。
游戏的复杂度定义为游戏中所使用的单词长度总和。
编写程序,求出使用一本给定的词典来玩这个游戏所能达到的游戏最大可能复杂度。
输入格式
输入文件的第一行,表示一个自然数N(1≤N≤16),N表示一本字典中包含的单词数量以下的每一行包含字典中的一个单词,每一个单词是由字母A、E、I、O和U组成的一个字符串,每个单词的长度将小于等于100,所有的单词是不一样的。
输出格式
输出文件仅有一行,表示该游戏的最大可能复杂度。
样例 #1
样例输入 #1
5
IOO
IUUO
AI
OIOOI
AOOI
样例输出 #1
16
分析
- 首先看到这个N(1≤N≤16),马上就反应过来了
- 搜索或状压dp
- 由于本蒟蒻刚开始学习状压dp,这篇博客讲的就是状压dp
正文~~
状压dp是啥
“状压DP 又叫集合动态规划。是以结合信息为状态的特殊的动态规划的问题。主要有传统集合动态规划和基于连通性状态压缩的动态规划两种。” ————百度
是不是感觉很高大尚?(我也觉得 )
他非常简(妙 )单(啊 )
状压dp的样子
- 我们回到题目:我们把每个单词看成每一个点,被选了标记成一,他就变成了这样一个样子

- 我们回到题目:我们把每个单词看成每一个点,被选了标记成一,他就变成了这样一个样子
怎么转移?
前置知识
- (<<):左移
- 在十进制上是乘法
- 在二进制上是把整体往左挪一位,例如:100 << 1 = 1000
- (>>): 右移,和左移原理一样,把整体往右移一位
- 对于每个状态,我们枚举这个点有没有选到:如100010这个状态没有选第三个点
- 怎么写代码?
- 这就要用到左移 和 与运算了
- 如果我想要表示一个100,表示第三个状态已被选怎么办?
- 很容易发现
100
=
1
<
<
(
3
−
1
)
100=1<<(3-1)
100=1<<(3−1)
- 于是我们可以总结:
想
要
表
示
第
i
个
点
被
选
=
1
<
<
(
i
−
1
)
想要表示第i个点被选=1<<(i-1)
想要表示第i个点被选=1<<(i−1)
- 于是我们就可以用 i & 1<<(j-1)(i表示当前状态,j表示当前枚举到的点)来表示i状态有没有选点j
考虑转移?
- 枚举每个状态,再枚举这个状态选了那些点,再由这些点进行转移
- 什么意思?
- 例如状态10001,这个状态包含1,5这2个点
- 如果点2可以接到点1后面
- 那么
f
[
11001
]
=
m
a
x
(
f
[
10001
]
+
v
,
f
[
11001
]
)
f[11001]=max(f[10001]+v,f[11001])
f[11001]=max(f[10001]+v,f[11001])
- 然后输出
f
[
(
1
<
<
n
)
−
1
]
f[(1<<n)-1]
f[(1<<n)−1]全部点被选即可
针对这一道题?
- 我们刚刚那一串分析有一个重要的
B
U
G
BUG
BUG!
- 那就是其他点怎么转到这个点?
- 其实我们只要将
f
f
f数组增加一维用来表示这个状态最后的字母是什么即可
- 我们刚刚那一串分析有一个重要的
C
o
d
e
:
Code:
Code:
#include<bits/stdc++.h>
using namespace std;
int n,dp[30][1<<16];
string a[20];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++)
dp[a[i][int(a[i].size()-1)]-'A'][1<<(i-1)]=int(a[i].size());//初始化
for(int i=1;i<=1<<n;i++){
for(int j=1;j<=n;j++){//考虑用j进行转移
if(!(i&1<<(j-1))) continue;//如果这个状态不包括这个点,就跳过
for(int k=1;k<=n;k++){
if(i&1<<(k-1)) continue;//如果状态选了k这个点,那么就不必要再选了
if(a[j][int(a[j].size())-1]-'A'!=a[k][0]-'A') continue;//如果接不上,也跳过
dp[a[k][int(a[k].size())-1]-'A'][i|(1<<(k-1))]=max(dp[a[j][int(a[j].size())-1]-'A'][i]+int(a[k].size()),dp[a[k][int(a[k].size())-1]-'A'][i|(1<<(k-1))]);
}
}
}
int maxx=0;
for(int i=1;i<=1<<n;i++){
for(int j=1;j<=n;j++){
maxx=max(maxx,dp[a[j][int(a[j].size())-1]-'A'][i]);
}
}
cout<<maxx;//由于不一定全选,所以枚举每个状态,输出即可
return 0;
}
推荐另外一道很相像的题:
吃奶酪
打代码去咯!
P1278 单词游戏【题解】(状压dp)的更多相关文章
- 洛谷 P1278 单词游戏 【状压dp】
题目描述 Io和Ao在玩一个单词游戏. 他们轮流说出一个仅包含元音字母的单词,并且后一个单词的第一个字母必须与前一个单词的最后一个字母一致. 游戏可以从任何一个单词开始. 任何单词禁止说两遍,游戏中只 ...
- O - Matching 题解(状压dp)
题目链接 题目大意 给你一个方形矩阵mp,边长为n(n<=21) 有n个男生和女生,如果\(mp[i][j]=1\) 代表第i个男生可以和第j个女生配对 问有多少种两两配对的方式,使得所有男生和 ...
- [BZOJ 1879][SDOI 2009]Bill的挑战 题解(状压DP)
[BZOJ 1879][SDOI 2009]Bill的挑战 Description Solution 1.考虑状压的方式. 方案1:如果我们把每一个字符串压起来,用一个布尔数组表示与每一个字母的匹配关 ...
- NOIP2017 宝藏 题解报告【状压dp】
题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖掘所有宝藏屋中的宝藏.但是 ...
- TZOJ 2289 Help Bob(状压DP)
描述 Bob loves Pizza but is always out of money. One day he reads in the newspapers that his favorite ...
- 【bzoj5161】最长上升子序列 状压dp+打表
题目描述 现在有一个长度为n的随机排列,求它的最长上升子序列长度的期望. 为了避免精度误差,你只需要输出答案模998244353的余数. 输入 输入只包含一个正整数n.N<=28 输出 输出只包 ...
- TZOJ 4912 炮兵阵地(状压dp)
描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P" ...
- POJ 1684 Corn Fields(状压dp)
描述 Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ ...
- 【uoj#37/bzoj3812】[清华集训2014]主旋律 状压dp+容斥原理
题目描述 求一张有向图的强连通生成子图的数目对 $10^9+7$ 取模的结果. 题解 状压dp+容斥原理 设 $f[i]$ 表示点集 $i$ 强连通生成子图的数目,容易想到使用总方案数 $2^{sum ...
- Codeforces Beta Round #8 C. Looking for Order 状压dp
题目链接: http://codeforces.com/problemset/problem/8/C C. Looking for Order time limit per test:4 second ...
随机推荐
- 2022最新版超详细的Maven下载配置教程、IDEA中集成maven(包含图解过程)、以及导入项目时jar包下载不成功的问题解决
文章目录 1.maven下载 2.maven环境变量的配置 3.查看maven是否配置成功 4.配置文件的修改 5.IDEA集成maven 6.导入项目时jar包下载不成功的问题解决 maven教程: ...
- 齐博x1标签实例:调用多个圈子同时调用贴子
下面讲解,在首页,如何调用圈子的同时也调用他们相关的贴子. 单单调用圈子,就像调用文章一样,很多人都能轻松实现,比如下面的代码 {qb:tag name="xxx" type=&q ...
- LcdTools如何自定义读写PX01 SSD2828寄存器
LcdToos打开相应的工程文件,连接PX01并开启点亮屏使LcdTools开关处于开启状态. 切到"测试设置"栏,在"Bridge控制"栏,在"Ad ...
- 图文详解丨iOS App上架全流程及审核避坑指南
App Store作为苹果官方的应用商店,审核严格周期长一直让用户头疼不已,很多app都"死"在了审核这一关,那我们就要放弃iOS用户了吗?当然不是!本期我们从iOS app上架流 ...
- 手把手教你使用LabVIEW实现Mask R-CNN图像实例分割
前言 前面给大家介绍了使用LabVIEW工具包实现图像分类,目标检测,今天我们来看一下如何使用LabVIEW实现Mask R-CNN图像实例分割. 一.什么是图像实例分割? 图像实例分割(Instan ...
- 实例解读丨关于GaussDB ETCD服务异常
摘要:本文通过对ETCD服务异常问题分析,代码展示解决方案. 本文分享自华为云社区<[实例状态]GaussDB ETCD服务异常>,作者:酷哥. 首先确认是否是虚拟机.网络故障 虚拟机故障 ...
- pycharm安装第三方的包
这里以安装selenium为例子 在file下找到settings 在弹出的窗口点击python interpreter ,然后在右侧点击[+] 在弹窗顶部输入要导入的包名,在下方列表找到对应包后,点 ...
- MvvmLight框架的基本使用
关于MvvmLight框架的介绍可以看这篇,说的很详细,在此记录下来以作复习,通过一个简单的例子说明MvvmLight的基本使用 https://www.cnblogs.com/3xiaolonglo ...
- K8S节点配置资源驱逐
#参考文章:https://www.cnblogs.com/zhangrui153169/p/15726165.html 当节点内存到达多少时.对节点的pod进行驱逐 [root@lecode-tes ...
- 【RPC和Protobuf】之RPC入门
一,概念 RPC:Remote procedure call(远程过程调用),分布式系统中不同节点之间流行的通信方式 服务端: 注: 1.执行下面的代码之后,会相应的启动一个tcp进程 C:\User ...