Codeforces 544E Remembering Strings 状压dp
题意:
给定n个长度均为m的字符串
以下n行给出字符串
以下n*m的矩阵表示把相应的字母改动成其它字母的花费。
问:
对于一个字符串,若它是easy to remembering 当 它存在一个字母。使得这个字母在这一列是独一无二的。
要使得n个字符串都是easy to remembering 的最小花费。
第一个例子是把第一列的4个a中3个a改动成别的字母。所以花费为3.
思路:
显然是个状压dp,但须要一点转化。
首先得到一个结论:
对于某一列,设这一列的字母是 a,a,b,b,a,d,c···
随意改动某种字母,都能使得包含该种字母的字符串变成unique
instance: 把全部的a字母都改动为别的字母,一定能使得改动后的字母与同列的其它字母不反复。
由于最多仅仅有20个字符串,也就是改动后的字母种类至多仅仅有20种。
然后状压已经easy to remembering的字符串的最小花费。
dp[i] 表示已经easy to remembering 的字符串状态为i时的最小花费。
两个转移:
1、直接改动字母
2、把这一列中全部与这个字母同样的字母都改动成别的字母。
当然能够剩下一个,剩下花费最大的那个就可以。
cost[i][j] 就表示除了花费最大的那个 同列中与str[i][j]字母同样的花费和。
bit[i][j] 表示哪些字符串 在第j列 与 a[i][j] 字母同样。
#include <iostream>
#include <string>
#include <vector>
#include <cstring>
#include <cstdio>
#include <map>
#include <queue>
#include <algorithm>
#include <stack>
#include <cstring>
#include <cmath>
#include <set>
#include <vector>
using namespace std;
template <class T>
inline bool rd(T &ret) {
char c; int sgn;
if (c = getchar(), c == EOF) return 0;
while (c != '-' && (c<'0' || c>'9')) c = getchar();
sgn = (c == '-') ? -1 : 1;
ret = (c == '-') ? 0 : (c - '0');
while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
ret *= sgn;
return 1;
}
template <class T>
inline void pt(T x) {
if (x <0) {
putchar('-');
x = -x;
}
if (x>9) pt(x / 10);
putchar(x % 10 + '0');
}
typedef long long ll;
typedef pair<ll, ll> pii;
const int inf = 1e9;
const int N = 21;
int n, m;
char s[N][N];
int a[N][N];
int dp[1 << N];
int bit[N][N], cost[N][N];
int main() {
rd(n); rd(m);
for (int i = 0; i < n; i++)scanf("%s", s[i]);
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)rd(a[i][j]);
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
{
int ans = 0, maxn = -inf;
for (int k = 0; k < n; k++)
if (s[i][j] == s[k][j])
{
ans += a[k][j];
maxn = max(maxn, a[k][j]);
bit[i][j] |= 1 << k;
}
ans -= maxn;
cost[i][j] = ans;
}
for (int i = 1; i < (1 << n); i++)dp[i] = inf;
dp[0] = 0;
for (int i = 0; i < (1 << n); i++)
{
for (int j = 0; j < n; j++)
if ((i & (1 << j)) == 0)
{
for (int k = 0; k < m; k++)
{
dp[i | (1 << j)] = min(dp[i | (1 << j)], dp[i] + a[j][k]);
dp[i | bit[j][k]] = min(dp[i | bit[j][k]], dp[i] + cost[j][k]);
}
}
}
pt(dp[(1 << n) - 1]);
return 0;
}
Codeforces 544E Remembering Strings 状压dp的更多相关文章
- Codeforces Round #302 (Div. 1) C - Remembering Strings 状压dp
C - Remembering Strings 思路:最关键的一点是字符的个数比串的个数多. 然后就能状压啦. #include<bits/stdc++.h> #define LL lon ...
- CF543C Remembering Strings 状压dp
Code: #include <cstdio> #include <algorithm> #include <cstring> #define setIO(s) f ...
- codeforces Diagrams & Tableaux1 (状压DP)
http://codeforces.com/gym/100405 D题 题在pdf里 codeforces.com/gym/100405/attachments/download/2331/20132 ...
- Codeforces 917C - Pollywog(状压 dp+矩阵优化)
UPD 2021.4.9:修了个 typo,为啥写题解老出现 typo 啊( Codeforces 题目传送门 & 洛谷题目传送门 这是一道 *2900 的 D1C,不过还是被我想出来了 u1 ...
- Codeforces 79D - Password(状压 dp+差分转化)
Codeforces 题目传送门 & 洛谷题目传送门 一个远古场的 *2800,在现在看来大概 *2600 左右罢( 不过我写这篇题解的原因大概是因为这题教会了我一个套路罢( 首先注意到每次翻 ...
- codeforces 21D. Traveling Graph 状压dp
题目链接 题目大意: 给一个无向图, n个点m条边, 每条边有权值, 问你从1出发, 每条边至少走一次, 最终回到点1. 所走的距离最短是多少. 如果这个图是一个欧拉回路, 即所有点的度数为偶数. 那 ...
- Codeforces 895C - Square Subsets 状压DP
题意: 给了n个数,要求有几个子集使子集中元素的和为一个数的平方. 题解: 因为每个数都可以分解为质数的乘积,所有的数都小于70,所以在小于70的数中一共只有19个质数.可以使用状压DP,每一位上0表 ...
- CodeForces 327E Axis Walking(状压DP+卡常技巧)
Iahub wants to meet his girlfriend Iahubina. They both live in Ox axis (the horizontal axis). Iahub ...
- Codeforces ----- Kefa and Dishes [状压dp]
题目传送门:580D 题目大意:给你n道菜以及每道菜一个权值,k个条件,即第y道菜在第x道后马上吃有z的附加值,求从中取m道菜的最大权值 看到这道题,我们会想到去枚举,但是很显然这是会超时的,再一看数 ...
随机推荐
- 【BZOJ2752】【线段树】高速公路
Description Y901高速公路是一条重要的交通纽带,政府部门建设初期的投入以及使用期间的养护费用都不低,因此政府在这条高速公路上设立了许多收费站. Y901高速公路是一条由N-1段路以及N个 ...
- 【BZOJ3673】【可持久化并查集】可持久化并查集 by zky
Description n个集合 m个操作操作:1 a b 合并a,b所在集合2 k 回到第k次操作之后的状态(查询算作操作)3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0<n ...
- js打开新的窗体不被浏览器阻止
转载自js弹出新窗口而不会被浏览器阻止的方法有时候希望可以用js另开新窗口,但用window.open方法打开窗口总是被浏览器阻止, 可以用下面的方法打开新窗口而不会遭到拦截 1.新添加一个Form ...
- C缩写
STL:Standard Template Library,标准模板库
- JQuery树形目录制作
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DT ...
- python之正则表达式备忘
一简介:就其本质而言,正则表达式(或 RE)是一种小型的.高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现.正则表达式模式被编译成一系列的字节码,然后由用 C ...
- ArcGis Engine 读取自定义prj坐标系文件时,中文名称乱码
今天测试时发现使用ArcMap自定义一个坐标系,将坐标系名称设置为中文,基准面名称选择为自定义后,然后保存成prj文件. 在自己的程序中读取该prj文件后,发现ISpatialReference 对象 ...
- Oracle问题解决(远程登录失败)
远程机: 安装 Oracle 的计算机: 本地机: 访问远程机 Oracle 的计算机. 一.问题描述 远程机安装 Oracle 成功. 本地机配置 InstantClient 后, PLSql De ...
- BZOJ 1823 满汉全席
Description 满汉全席是中国最丰盛的宴客菜肴,有许多种不同的材料透过满族或是汉族的料理方式,呈现在數量繁多的菜色之中.由于菜色众多而繁杂,只有极少數博学多闻技艺高超的厨师能够做出满汉全席,而 ...
- 清除html的标签和行内样式
function shieldStyle(){ this._styleStartArr=["<span","<p","<strong ...