状压dp 图论 难题 E. String Transformation 2

状压dp 图论 难题 E. String Transformation 2

题目大意:

你有两个串, \(A\)\(B\) ,你可以对A进行操作使得 \(A=B\)

操作:选择k个相同的字符,然后把他们修改成相同的字符。

题目保证 \(A\) \(B\) 只有字母表的前二十个字符。

题解:

这个题目确实很难,不过刘雨小姐姐也是真的强,把这个题目转化成求最大的有向无环图。

这个题目的题解答案就是 :\(2*n-S-1\) 这个\(S\) 就是最大有向无环图的点的数量。

至于为什么是这个答案呢?

假设 \(A\) 变成 \(B\) 是一个有向无环图,那么就是说和版本1是一样的。

那么对这个图标一个优先级,让优先级低的往优先级高的跳。

注意这个点的3和4的优先级无所谓,但是标4为3,那么5一定是4。

很容易发现答案就是这个有向无环图的点的数量-1,就是要跳的次数,因为版本1规定了跳的方向,一定是往字符大的方向跳,所以不会形成环,就是一个有向无环图,那么如果加入了一个点,使得这个图出现环了呢?

这样的话,是不是最多就要多跳两次。

因为这个点一定要跳出去,所以一次,别人一定要跳到它,所以一次,至少也要两次,所以加入的这个点如果构成环了,那么会多跳两次。

本来是每一个点的贡献都是2,但是形成有向无环图之后它只要跳出去一次就一定可以到达终点,所以会减少一次,对于终点1,就只要0次,减少了两次。

所以最后答案就是 :\(2*n-S-X\) 其中 \(S\) 表示所有独立的最大有向无环图的点数相加,\(X\) 表示独立的有向无环图的数量。

最后怎么求最大的有向无环图呢,这个可以状压求。

首先预处理一下每一个点指向的位置,定义\(dp[s]\) 表示状态 \(s\) 下,是否为一个有向无环图,每一个点加入这个状态的要求它指向的点都不在状态 \(s\) 中,那么就可以加入。

判断图的数量可以用并查集。

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn = 1e5+10;
char A[maxn],B[maxn];
int f[30],to[30];
int findx(int x){
    return f[x]==x?x:f[x]=findx(f[x]);
}
void unite(int x,int y){
    x = findx(x);
    y = findx(y);
    if(x==y) return ;
    f[x]=y;
}
bool dp[1<<21];
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        int n;
        scanf("%d",&n);
        scanf("%s%s",A+1,B+1);
        for(int i=0;i<20;i++) f[i]=i,to[i]=0;
        for(int i=1;i<=n;i++){
            int x = A[i]-'a', y = B[i]-'a';
            to[x]|=(1<<y);
            unite(x,y);
        }
        int ans = 40;
        for(int i=0;i<20;i++) if(findx(i)==i) ans--;
        memset(dp,false,sizeof(dp));
        dp[0]=true;
        int maxs = 0;
        for(int s=0;s<(1<<20);s++){
            if(!dp[s]) continue;
            int cur = 0;
            for(int i=0;i<20;i++){
            	int tmp = 1<<i;
            	if(tmp&s) cur++;
                if(to[i]&s) continue;
                dp[s|tmp]=true;
            }
            maxs=max(maxs,cur);
        }
        printf("%d\n",ans-maxs);
    }
    return 0;
}

/*
2
4
cabc
abcb
 */
posted @ 2020-07-29 15:23  EchoZQN  阅读(358)  评论(2编辑  收藏  举报