Codeforces 题面传送门 & 洛谷题面传送门

神奇的强迫症效应,一场只要 AC 了 ABDEF,就一定会把 C 补掉(

感觉这个 C 难度比 D 难度高啊……

首先考虑对问题进行初步转化。显然对于 \(s_i=s_j,t_i=t_j\)​ 的 \((i,j)\)​,我们肯定会将它们放在一起操作,这启发我们将所有 \((s_i,t_i)\)​ 看作一个二元组,那么如果我们把“每一步将字符 \(x\) 变为 \(y\)”这样的操作视作一条从 \(x\) 连向 \(y\),权值为当前是第几次操作。那么一个连边方式合法,当且仅当对于所有二元组 \((s,t)\) 都存在一条 \(s\to t\) 的路径,满足其经过的所有边的权值单调递增。

考虑怎样解决这个问题,首先注意到 \(39\)​​​ 次操作一定是可行的,具体来说就 \(’a’\to’b’\to’c’\to\cdots\to’t’\to’a’\to\cdots’t’\)​​​ 连两个环,这样一定能保证对于所有 \((x,y)\)​​ 都存在符合要求的路径,不过注意到我们并不一定要所有 \((x,y)\)​​ 之间都存在符合要求的路径,因此考虑从这个角度入手减少操作次数。这里直接给出结论:如果我们设 \(n=20\)​​ 表示图中的点数,对于所有二元组 \(s\to t\)​​ 我们再建一张图 \(G\)​​,并设 \(S\)​​ 表示满足 \(S\subseteq G\)​​,\(S\)​​ 为 DAG 且 \(S\)​​ 包含的点数最多的导出子图,\(c\)​ 表示 \(G\)​ 中弱连通块的个数,那么 \(res=2n-S\)​ 中点的个数 \(-c\)​。​

证明:首先我们来说明我们能达到这张图,我们考察 \(G\) 中每一个弱连通块,显然它有一部分点是包含在 \(S\) 当中的对吧,对于这部分点我们将它们按拓扑序编号 \(1,2,3,\cdots,k\),其中 \(k\) 表示该连通块中包含在 \(S\) 中的点数,对于剩余的点我们随意编号 \(k+1,k+2,\cdots,m\),那么我们考虑这样连边:\(k\to k+1\to k+2\to\cdots\to m\to 1\to 2\to\cdots\to k\to k+1\to k+2\to\cdots m\),这样总边数显然是 \(2m-k-1\),不难发现这样一来,该连通块中只有 DAG 中拓扑序从后往前的二元组无法到达,而由于这是一个 DAG,因此这样的点之间没有边,符合要求,把它们的贡献累加起来就是 \(2n-S\) 中点的个数 \(-c\)。

接下来来说明这就是本题操作次数的下界。我们不妨想象这样一个在一个初始没有边的图中加边的过程,每加入一条边有两种可能,要么沟通了原本不在同一个弱连通块中的两点,由最终得到的图中恰有 \(c\)​​​ 个连通块可知这样的边至少有 \(n-c\)​​​ 条,要么连接了两个原本就在同一连通块中的边,对于这样的边我们维护一个 \(T\)​​​ 表示当前无法沿着一个合法的路径到达本身的点集,那么显然初始 \(T=\{1,2,3\cdots,n\}\)​​​,而当我们加入 \((x,y)\)​​​ 这条边时,最多使 \(y\)​​​ 这个点能够到达本身,即 \(T\)​​​ 的大小最多减 \(1\)​​​,因此如果最终 \(|T|=x\)​​​,那么操作次数 \(\ge n-c+n-x\)​​​,又显然最终 \(T\)​​​ 中的点必须形成一个 DAG,否则其中必然存在圈 \(x_1\to x_2\to\cdots\to x_k\to x_1\)​​,由于这些边必须可达,因此可以推出 \(x_1\)​​ 可以到达 \(x_1\)​​,与 \(T\)​​ 的定义矛盾。因此最终 \(x\le\)​​ 上文中 \(S\)​​ 的点数,也就证明了答案的下界。据说这方法有个名字叫势能法?反正总之很神仙就对了(

有了这个性质之后题目就很容易了。\(n,c\) 都很容易求得。至于怎样求 \(S\) 的大小……注意到这题最多涉及到 \(20\) 个字母,即点数最多 \(20\),一脸状压,直接枚举 \(S\) 的点集并 check 是 \(2^{20}20^2\) 的,不知道能不能通过。考虑加点《小优化》,我们设 \(dp_S\) 表示 \(S\) 的导出子图是否是一个 DAG,那么我们考虑每次增加一个点 \(x\) 作为 DAG 中出度为 \(0\) 的点并检验这个点连出去的边中,是否有边指向 \(S\) 中的点,如果有那么 \(dp_{S\cup\{x\}}=0\),否则 \(dp_{S\cup\{x\}}=1\),这样是 \(2^{20}·20\) 的,可以通过。

const int ALPHA=20;
const int MAXN=1e5;
const int MAXP=1048576;
int n,f[ALPHA+2],fr[ALPHA+2];
char s[MAXN+5],t[MAXN+5];
bool dp[MAXP+5];
void clear(){memset(f,-1,sizeof(f));memset(fr,0,sizeof(fr));memset(dp,0,sizeof(dp));}
int find(int x){return (!~f[x])?x:f[x]=find(f[x]);}
void merge(int x,int y){x=find(x);y=find(y);if(x^y) f[x]=y;}
void solve(){
scanf("%d%s%s",&n,s+1,t+1);clear();
for(int i=1;i<=n;i++){
int x=s[i]-'a',y=t[i]-'a';
fr[x]|=(1<<y);merge(x,y);
} int res=ALPHA<<1,mx=0;
for(int i=0;i<ALPHA;i++) if(find(i)==i) res--;
dp[0]=1;for(int i=0;i<MAXP;i++) if(dp[i]){
chkmax(mx,__builtin_popcount(i));
for(int j=0;j<ALPHA;j++) if(~i>>j&1){
if((fr[j]&i)==0) dp[i|(1<<j)]=1;
}
} printf("%d\n",res-mx);
}
int main(){
int qu;scanf("%d",&qu);
while(qu--) solve();
return 0;
}

Codeforces 1383C - String Transformation 2(找性质+状压 dp)的更多相关文章

  1. 没有找零 状压dp

    没有找零 状压dp 约翰到商场购物,他的钱包里有K(1 <= K <= 16)个硬币,面值的范围是1..100,000,000.约翰想按顺序买 N个物品(1 <= N <= 1 ...

  2. Codeforces 1225G - To Make 1(bitset+状压 dp+找性质)

    Codeforces 题目传送门 & 洛谷题目传送门 还是做题做太少了啊--碰到这种题一点感觉都没有-- 首先我们来证明一件事情,那就是存在一种合并方式 \(\Leftrightarrow\) ...

  3. Codeforces Gym 100610 Problem K. Kitchen Robot 状压DP

    Problem K. Kitchen Robot Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/10061 ...

  4. Educational Codeforces Round 13 E. Another Sith Tournament 状压dp

    E. Another Sith Tournament 题目连接: http://www.codeforces.com/contest/678/problem/E Description The rul ...

  5. [BZOJ3312][USACO]不找零(状压DP)

    Description 约翰带着 N 头奶牛在超市买东西,现在他们正在排队付钱,排在第 i 个位置的奶牛需要支付 Ci元.今天说好所有东西都是约翰请客的,但直到付账的时候,约翰才意识到自己没带钱,身上 ...

  6. CF1103D Codeforces Round #534 (Div. 1) Professional layer 状压 DP

    题目传送门 https://codeforces.com/contest/1103/problem/D 题解 失去信仰的低水平选手的看题解的心路历程. 一开始看题目以为是选出一些数,每个数可以除掉一个 ...

  7. FZU 2093 找兔子 状压DP

    题目链接:找兔子 n的范围是[1, 15],可以用0 到 (1<<n)-1 的数表示全部状态,用dp[i] = t表示到达状态i的最少时间是t,对于每个点,如果它能到达的所有点在t秒时都已 ...

  8. Codeforces 279D The Minimum Number of Variables 状压dp

    The Minimum Number of Variables 我们定义dp[ i ][ mask ]表示是否存在 处理完前 i 个a, b中存者 a存在的状态是mask 的情况. 然后用sosdp处 ...

  9. codeforces#580 D. Kefa and Dishes(状压dp)

    题意:有n个菜,每个菜有个兴奋值,并且如果吃饭第i个菜立即吃第j个菜,那么兴奋值加ma[i][j],求吃m个菜的最大兴奋值,(n<=18) 分析:定义dp[status][last],statu ...

随机推荐

  1. JavaScript中的模式匹配

    JavaScript中的模式匹配 模式是用于转换输入数据的规则. 以将数据与一个或多个逻辑结构进行比较,将数据分解为各个构成部分,或以各种方式从数据中提取信息. 安装 JavaScript已经实现模式 ...

  2. .Net2.0连接PG数据注意事项

    .Net2.0连接PG数据注意事项 第一次用.net操作PG[.NET2.0] 一:Npgsql版本问题 1:如果是.net2.0  建议用2.0.11.0[NuGet搜索npgsql第一个的最低版本 ...

  3. Noip模拟14 2021.7.13

    T1 队长快跑 本身dp就不强的小马看到这题并未反映过来是个dp(可能是跟题面太过于像那个黑题的队长快跑相似) 总之,基础dp也没搞出来,不过这题倒是启发了小马以后考试要往dp哪里想想 $dp_{i, ...

  4. longest-consecutive-sequence leetcode C++

    Given an unsorted array of integers, find the length of the longest consecutive elements sequence. F ...

  5. 第02课 OpenGL 多边形

    你的第一个多边形: 在第一个教程的基础上,我们添加了一个三角形和一个四边形.也许你认为这很简单,但你已经迈出了一大步,要知道任何在OpenGL中绘制的模型都会被分解为这两种简单的图形.读完了这一课,你 ...

  6. 关于dns服务工作的原理,和配置的细节理解。

    dns服务器相关 1,dns原理,也就是迭代,和递归查询.将域名解析为ip的过程. 一次完整的查询请求经过的流程: Client -->hosts文件 -->DNS Service Loc ...

  7. element-UI 中的upload组件如何添加token?

    <el-upload :show-file-list="false" :on-error="errmsg" :headers="headers& ...

  8. JuiceFS CSI Driver 的最佳实践

    文章根据 Juicedata 工程师朱唯唯,在云原生 Meetup 杭州站所作主题演讲<JuiceFS CSI Driver 的最佳实践>整理而成. 大家好,我是来自 Juicedata ...

  9. Redis网络库源码分析(2)之启动服务器

    一.从main开始 main函数定义在server.c中,它的内容如下: //server.c int main() { signal(SIGPIPE, SIG_IGN); //忽略SIGPIPE信号 ...

  10. SpringCould | Nacos与Feign

    服务注册Nacos 介绍 概念 一个更易于构建云原生应用的动态服务发现.配置管理和服务管理平台. Nacos: Dynamic Naming and Configuration Service Nac ...