CF 543C Remembering Strings
https://cn.vjudge.net/problem/CodeForces-543C
题目
You have multiset of n strings of the same length, consisting of lowercase English letters. We will say that those strings are easy to remember if for each string there is some position i and some letter c of the English alphabet, such that this string is the only string in the multiset that has letter c in position i.
For example, a multiset of strings {"abc", "aba", "adc", "ada"} are not easy to remember. And multiset {"abc", "ada", "ssa"} is easy to remember because:
- the first string is the only string that has character c in position 3;
- the second string is the only string that has character d in position 2;
- the third string is the only string that has character s in position 2.
You want to change your multiset a little so that it is easy to remember. For aij coins, you can change character in the j-th position of the i-th string into any other lowercase letter of the English alphabet. Find what is the minimum sum you should pay in order to make the multiset of strings easy to remember.
Input
The first line contains two integers n, m (1 ≤ n, m ≤ 20) — the number of strings in the multiset and the length of the strings respectively. Next n lines contain the strings of the multiset, consisting only of lowercase English letters, each string's length is m.
Next n lines contain m integers each, the i-th of them contains integers ai1, ai2, ..., aim (0 ≤ aij ≤ 106).
Output
Print a single number — the answer to the problem.
题解
把字符串一行一行地写出来
$n\leqslant 20$就暗示了可以二进制压位(压行)……
设$dp[k]$为容易记住的状态为k时的最小花费
有两种操作
- 改变记不住的行中的一个字符(n小于26,一定可以找到另外的字母),让这个字符串容易记
- 改变这一列中有与这个字符相同的字符的字符串,贪心保留最贵的位置,让这些字符串容易记
其中2是贪心多次1
但填表法可以按这种策略……
- 改变第一个记不住的行中的一个字符
- 改变第一个记不住的行中的一个字符的其他相同的行
反过来就是
- 从第一个行记不住的状态转移到现在的状态
- 从这些行记不住的转移到现在的状态
虽然其中2的这些行应该一次性记完,但一个字符串可以有多个独特的字符(算记多次),可能更省钱
如
5 2
aa
aa
ab
bb
bb
1 100
100 100
1 1
100 100
100 1
修改为
Ca
aa
DE
bb
bF
但是感觉还是有点牵强
(过了的代码)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<iomanip>
#include<queue> #define REP(r,x,y) for(register int r=(x); r<(y); r++)
#define REPE(r,x,y) for(register int r=(x); r<=(y); r++)
#define PERE(r,x,y) for(register int r=(x); r>=(y); r--)
#ifdef sahdsg
#define DBG(...) printf(__VA_ARGS__)
#else
#define DBG(...) (void)0
#endif using namespace std;
typedef long long LL;
typedef pair<LL, LL> pll;
typedef pair<int, int> pii; template <class T>
inline void read(T& x) {
char c=getchar();
int f=1;x=0;
while(!isdigit(c)&&c!='-')c=getchar();
if(c=='-')f=-1,c=getchar();
while(isdigit(c)){x=x*10+c-'0';c=getchar();}x*=f;
}
template <class T,class... A>void read(T&t,A&...a){read(t);read(a...);} char st[27][27];
int c[27][27];
int dp[1<<20];
int ca[27][27],ka[27][27];
inline int lg2(int x) {
int k=0;
while(x) x>>=1, k++;
return k;
}
int main() {
int n,m; read(n,m);
REP(i,0,n) fgets(st[i],27,stdin);
REP(i,0,n) REP(j,0,m) {
read(c[i][j]);
}
memset(dp,0x3f,sizeof dp);
REP(j,0,m) {
REP(i,0,n) {
ca[i][j]=0;
int maxx=0;
REP(k,0,n) if(st[i][j]==st[k][j]) {
maxx=max(maxx,c[k][j]);
ca[i][j]+=c[k][j];
ka[i][j]|=1<<k;
}
ca[i][j]-=maxx;
}
}
dp[0]=0;
REP(k,0,1<<n) {
int lb=(k)&(-k);
int li=lg2(lb)-1;
REP(j,0,m) {
dp[k]=min(dp[k],dp[k^(k&ka[li][j])]+ca[li][j]);
dp[k]=min(dp[k],dp[k^lb]+c[li][j]);
}
}
printf("%d\n", dp[(1<<n)-1]);
return 0;
}
CF 543C Remembering Strings的更多相关文章
- Codeforces 543C Remembering Strings(DP)
题意比较麻烦 见题目链接 Solution: 非常值得注意的一点是题目给出的范围只有20,而众所周知字母表里有26个字母.于是显然对一个字母进行变换后是不影响到其它字符串的. 20的范围恰好又是常见状 ...
- Codeforces Round #302 (Div. 1) C - Remembering Strings 状压dp
C - Remembering Strings 思路:最关键的一点是字符的个数比串的个数多. 然后就能状压啦. #include<bits/stdc++.h> #define LL lon ...
- Codeforces Round #302 (Div. 1) C. Remembering Strings DP
C. Remembering Strings Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/5 ...
- CF Set of Strings
Set of Strings time limit per test 1 second memory limit per test 256 megabytes input standard input ...
- CF Vitaly and Strings
Vitaly and Strings time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- Codeforces 544E Remembering Strings 状压dp
题目链接 题意: 给定n个长度均为m的字符串 以下n行给出字符串 以下n*m的矩阵表示把相应的字母改动成其它字母的花费. 问: 对于一个字符串,若它是easy to remembering 当 它存在 ...
- codeforces 543 C Remembering Strings
题意:若一个字符串集合里的每一个字符串都至少有一个字符满足在i位上,仅仅有它有,那么这个就是合法的,给出全部串的每一个字符修改的花费,求变成合法的最小代价. 做法:dp[i][j].前i个串的状态为j ...
- CF 149E Martian Strings 后缀自动机
这里给出来一个后缀自动机的题解. 考虑对 $s$ 的正串和反串分别建后缀自动机. 对于正串的每个节点维护 $endpos$ 的最小值. 对于反串的每个节点维护 $endpos$ 的最大值. 这两个东西 ...
- CF543C Remembering Strings 状压dp
Code: #include <cstdio> #include <algorithm> #include <cstring> #define setIO(s) f ...
随机推荐
- Docker进阶之五:容器管理
容器管理 一.创建容器常用选项 docker container --help 指令 描述 资源限制指令 -i, --interactive 交互式 -m,--memory 容器可以使用的最大内存量 ...
- Django-restframework 之频率源码分析
Django-restframework 之频率源码分析 一 前言 经过权限判断之后就是进行频率的判断了,而频率的判断和权限又不一样,认证.权限和频率的执行流程都差不多,使用配置里面的相关类来进行判断 ...
- 戏说程序猿之cannot find the object
“别开玩笑了,程序员哪里需要对象!” 程序员难找对象原因无非如下: 1.工作时间长,恋爱时间少 2.性格偏于内向,不主动 3.不注意个人形象 程序员爱情观: 爱情就是死循环,一旦执行就陷进去了: 爱上 ...
- servlet doGet()方法获取字符串乱码问题
当你遇到ajax向servlet发送数据出现乱码问题的时候不要惊慌,现有以下两个解决办法 (1)在doGet和doPost方法中添加以下代码 request.setCharactersEncoding ...
- VR一体机如何退出FFBM
Fast Factory Boot Mode(FFBM)是一种半开机的模式,它的主要目的是方便工厂测试,提高生产效率.正常情况下终端用户是不会碰到的.但售后的同学最近连续收到几台客户退 ...
- WPF:浅析Dispatcher
本人文笔差.还是直接上代码吧.(本文假设你对WPF中的Dispatcher有一定的了解) 你觉得下面的代码可以正常执行吗? private void Button_Click(object sende ...
- 快速排序实现及其pivot的选取
coursera上斯坦福的算法专项在讲到快速排序时,称其为最优雅的算法之一.快速排序确实是一种比较有效的排序算法,很多类库中也都采用了这种排序算法,其最坏时间复杂度为$O(n^2)$,平均时间复杂度为 ...
- PO,VO,TO,BO,DAO,POJO的解释
java的(PO,VO,TO,BO,DAO,POJO)解释 O/R Mapping 是 Object Relational Mapping(对象关系映射)的缩写.通俗点讲,就是将对象与关系数据库绑定 ...
- Java三大特性
Java 三大特性,算是Java独特的表现,提到Java 的三大特性, 我们都会想到封装, 继承和多态 这是我们Java 最重要的特性. 封装(Encapsulation) : 封装:是指隐藏对象的属 ...
- lua os.date函数定义和示例
os.date函数定义 原型:os.date ([format [, time]]) 解释:返回一个按format格式化日期.时间的字串或表. lua源码中os.date的注释如下: --- --- ...