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 ...
随机推荐
- 齐博x1标签实例:标签如何调用论坛内容
论坛的内容不像CMS其它模块可以直接用变量 {$rs.content} 因为论坛的内容数据表是放在另一个表的,单独分开的. 当前也是为了考试效率问题而这样设计的. 所以他的调用要用下面的代码 {:fu ...
- 使用 Windows Core Audio APs 进行 Loopback Recording 并生成 WAV 文件
参考文档 COM Coding Practices Audio File Format Specifications Core Audio APIs Loopback Recording #inclu ...
- 关于引用JS和CSS文件刷新浏览器缓存问题,部署服务器后客户端样式不刷新
问题描述 对样式的css文件进行了修改,部署到服务器后访问发现页面展示不正常,但是刷新之后就会展示正常. 问题分析 研究之后发现可能的原因有 css文件过大,加载缓慢 本地缓存问题,虽然服务器修改了c ...
- vuex和浏览器【sessionStorage,localStorage ..】 得区别
1.Vuex的主要作用是用来共享和管理数据,那为什么不直接使用浏览器缓存呢?2.Vuex和浏览器缓存策略的根本区别是什么?3.Vuex,state仓库中的数据流是单向同步的,那为什么可以在action ...
- RAID5部署
软RAID与备份盘 1.此处我们还用刚才的4块盘做演示,三块盘做raid,一块盘做备份盘,防止磁盘故障 我们以raid 5 来配置三块磁盘 加上一块备份盘 [root@local-pyyu tmp]# ...
- Mysql InnoDB Buffer Pool
参考书籍<mysql是怎样运行的> 系列文章目录和关于我 一丶为什么需要Buffer Pool 对于InnoDB存储引擎的表来说,无论是用于存储用户数据的索引,还是各种系统数据,都是以页的 ...
- pod(七):静态pod
目录 一.系统环境 二.前言 三.静态pod 3.1 何为静态pod 3.2 创建静态pod 3.2.1 使用--pod-manifest-path指定静态pod目录 3.2.2 静态pod默认目录/ ...
- Python基础之模块:6、hashlib模块 subprocess模块 logging模块
目录 一.hashlib模块 1.简介 2.基本操作与用法 二.subprocess模块 1.简介 2.基本操作与用法 三.logging模块 1.简介 2.基本操作与用法 一.hashlib模块 1 ...
- day08-XML
XML 官方文档:https://www.w3school.com.cn/xml/index.asp 1.为什么需要xml? 需求1:两个程序间进行数据通信? 需求2:给一台服务器,做一个配置文件,当 ...
- 【Spring系列】- 手写模拟Spring框架
简单模拟Spring 生命不息,写作不止 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! 前言 上次已经学习了 ...