• HNOI模拟 Day3.22


    第一题: 盾盾的打字机 (drdrd) 
    【题目描述】 
    盾盾有一个非常有意思的打字机,现在盾哥要用这台打字机来打出一段文章。 
    由于有了上次的经验,盾盾预先准备好了一段模板 A 存在了内存中,并以此为基础来 
    打出文章 B。盾盾每次操作可以将内存中的某一个字符改成另一个字符,或者在某一个位置 
    插入一个字符,或者删除某一个位置上的字符。另外,为了避免自己预存的模板太腿反而浪 
    费时间,盾哥在所有操作之前会斟酌一下选择留下模板 A 的某一个最优的子串以保证操作 
    次数尽量少(当然盾盾也可以全保留或一个都不留),这一步不计入操作次数。 
    试求盾盾要打出文章 B 的最少操作次数。 
    子串是指母串中连续的一段。 
    【输入数据】 
    输入包含多组数据。 
    对于每组数据,两行,分别表示 A 和 B。 
    【输出数据】 
    每组数据一行,一个数,表示最少操作次数。 
    【输入样例】 
    aaaaa 
    aaa 
    abcabc 
    bcd 
    abcdef 
    klmnopq 
    【输出样例】 
    0 1 7 
    【 数据约定】 
    30% : |A|, |B| <= 10 
    100% : 1 <= |A|, |B| <= 1000, 数据组数 <= 10, 输入的串中只包含小写字 
    母 

     

    用状态 f[i][j]表示第一个串到了第 i 位,第二个串到了第 j 为的最优值,转移就枚举下一
    位怎么做。
    注意边界条件。

     

    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;

    typedef long long LL;

    #define INF 0x7fffffff
    #define MAXN 1010

    int dp[MAXN][MAXN];

    char a[MAXN],b[MAXN];

    int lena,lenb;

    int check(int x,int y)
    {
    if (x!=y)
    return 1;
    return 0;
    }

    bool work()
    {
    for (int i=0;i<=lena-lenb;i++)
    if (strncmp(a+i,b,lenb)==0)
    return true;
    return false;
    }

    int main()
    {
    freopen("drdrd.in","r",stdin);freopen("drdrd.out","w",stdout);
    while (scanf("%s",a)!=EOF)
    {
    memset(dp,127/3,sizeof(dp));
    scanf("%s",b);
    lena=strlen(a);
    lenb=strlen(b);
    if (lena>=lenb && work())
    {
    printf("0 ");
    continue;
    }
    for (int i=0;i<=lena;i++)
    {
    dp[i][0]=0;
    for (int j=0;j<=lenb;j++)
    {
    dp[i+1][j+1]=min(dp[i+1][j+1],dp[i][j]+check(a[i],b[j]));
    dp[i+1][j]=min(dp[i+1][j],dp[i][j]+1);
    dp[i][j+1]=min(dp[i][j+1],dp[i][j]+1);
    }
    }
    int ans=INF;
    for (int i=0;i<=lena;i++)
    ans=min(ans,dp[i][lenb]);
    printf("%d ",ans);
    }
    return 0;
    }

    第二题:社交网络(netrd)
    【题目描述】
    给定一个 N 个点 M 条边的无向图,你要连最少的边使得图连通。求方案数 mod P 的值。
    【输入数据】
    第一行三个数, N,M,P。
    接下来 M 行,每行两个数 x,y,表示 x 和 y 之间有一条边。
    【输出数据】
    仅一行, 一个数,即方案数。
    【输入样例】
    4 1 1000000000
    1 4
    【输出样例】
    8
    【样例解释】
    {(1, 2), (1, 3)} {(1, 2), (2, 3)} {(1, 2), (4, 3)} {(1, 3), (3, 2)}
    {(1, 3), (4, 2)} {(4, 2), (2, 3)} {(4, 2), (4, 3)} {(4, 3), (3, 2)}
    【数据约定】
    30% : N <= 10
    另 20% : M = 0
    100 : N <= 10 ^ 5, M <= 10 ^ 5, 1 <= P <= 10 ^ 9

     

    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;

    typedef long long LL;

    #define N 100010

    LL n,m,p;
    LL ans;

    int t;
    int x,y;
    int f[N],g[N];

    int find(int x)
    {
    return f[x]==x ? x : f[x]=find(f[x]);
    }

    int PowerMod(int a, int b, int c)
    {

    LL ans=1;
    LL k=a%c;
    while (b)
    {
    if (b&1)
    ans=1LL*ans*k%c;
    b>>=1;
    k=1LL*k*k%c;
    }
    return ans;
    }

    int main()
    {
    freopen("netrd.in","r",stdin);freopen("netrd.out","w",stdout);
    scanf("%lld%lld%lld",&n,&m,&p);
    if (!m)
    {
    LL ans=PowerMod(n,n-2,p);
    printf("%lld ",ans);
    return 0;
    }
    for (int i=1;i<=n;i++)
    f[i]=i;
    for (int i=1;i<=m;i++)
    {
    scanf("%d%d",&x,&y);
    f[find(x)]=find(y);
    }
    for (int i=1;i<=n;i++)
    g[find(i)]++,t+=(f[i]==i);
    if (t==1)
    {
    printf("%d",1%p);
    return 0;
    }
    LL ans=PowerMod(n,t-2,p);
    for (int i=1;i<=n;i++)
    if (g[i])
    ans=1LL*ans*g[i]%p;
    printf("%lld",ans);
    return 0;
    }

    树的 prufer 编码
    如果把一开始就连在一起的点缩在一起,我们相当于要求一个带“点权”的图的生成树
    方案数。
    用树的 prufer 编码来考虑。在 prufer 序列中,每个点的度数就是它在其中的出现次数+1,
    而每个点的每个度数都可以分配给他真正包含的点中的任意一个,用 a 表示包含的点数,
    d 表示度数,所以最后的方案数就是π (a[i] ^ d[i]),在序列中每次考虑往后加一个数,都
    有∑d[i] = n 种选择,所以最后的答案就是 n ^ (n-2) * π (a[i])。

     

     

  • 相关阅读:
    DQL、DML、DDL、DCL的概念与区别
    TeamViewer
    构建属于自己的ORM框架之二--IQueryable的奥秘
    某考试 T2 sum
    某考试 T1 line
    bzoj 2153: 设计铁路
    [SCOI2010]序列操作
    [SCOI2010]字符串
    [SCOI2010]传送带
    bzoj 2694: Lcm
  • 原文地址:https://www.cnblogs.com/yangjiyuan/p/5320194.html
Copyright © 2020-2023  润新知