• 单词


    小y有n个长度为m,且只含x,y,z的单词,给定相似度的定义:两个单词相同位相同的字母数

    d=∑[Ai==Bi]

    求相似度为0~m的单词对有多少个

    注意:(x,y)=(y,x)不考虑(x,x)

    输入:

    n m

    n个长度为m的单词

    输出:

    m+1行

    第i行表示相似度为i-1时,单词对数

    样列输入:

    4 3

    xyz

    xyz

    zzx

    xzz

    输出:

    2

    1

    2

    1

    范围:n*m<=100000

    (分类讨论)暴力+dp

    n*m<=100000所以n大m就小,m大n就小

    m>=12时,n小直接枚举区间暴力判断

    m<=12时,我们用状压dp

    用0表示x,1表示y,2表示z

    用3进制数表示

    f[s][p]表示状态为s,相似度为p的对数

    每一次修改状态中一个数

    f[s'][p-1]+=f[s][p];

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 using namespace std;
     6 typedef long long ll;
     7 ll pw[15],f[550001][13],ff[550001][13],ans[100001];
     8 ll s[550001];
     9 int n,m;
    10 char str[100001];
    11 void work1()
    12 {int i,j,p,l;
    13     for (i=1; i<=n; i++)
    14     {int now=0;
    15         for (j=1; j<=m; j++)
    16         {
    17             now*=3;
    18                 char ch=getchar();
    19                 while (ch<'x'||ch>'z') ch=getchar();
    20             now+=ch-'x';
    21         }
    22       s[now]++;
    23     }
    24     pw[0]=1;
    25       for (i=1;i<=m;i++) pw[i]=pw[i-1]*3;
    26       for (i=0;i<pw[m];i++) ff[i][m]=s[i];
    27       for (i=0;i<m;i++)
    28       {memcpy(f,ff,sizeof(f));
    29            for (j=0;j<pw[m];j++)
    30            {
    31                ll s1=j/pw[i]%3,s2=j-s1*pw[i];
    32                for (p=0;p<=2;p++)
    33                if (p!=s1)
    34             {
    35                    for (l=m-i;l<=m;l++) f[s2+p*pw[i]][l-1]+=ff[j][l];
    36                }
    37            }
    38            memcpy(ff,f,sizeof(f));
    39       }
    40       for (i=0;i<pw[m];i++)
    41       {
    42           for (j=0;j<=m;j++)
    43            ans[j]+=s[i]*ff[i][j];
    44       }
    45       ans[m]-=n;
    46     for (i=0;i<=m;i++) ans[i]/=2;
    47 }
    48 void work2()
    49 {int i,j,l;
    50     for (i=0; i<n*m; i++)
    51     {
    52         char ch=getchar();
    53         while (ch<'x'||ch>'z') ch=getchar();
    54         str[i]=ch;
    55     }
    56     for (i=0; i<n; i++)
    57         for (j=0; j<i; j++)
    58         {
    59             int cnt=0;
    60             for (l=0; l<m; l++)
    61                 if (str[i*m+l]==str[j*m+l])
    62                     cnt++;
    63             ans[cnt]++;
    64         }
    65 }
    66 int main()
    67 {int i;
    68     cin>>n>>m;
    69     if (m<=12) work1();
    70     else work2();
    71     for (i=0; i<=m; i++)
    72         printf("%lld
    ",ans[i]);
    73 }
  • 相关阅读:
    整理打印PI值
    使用自连接、for xml path('')和stuff合并显示多行数据到一行中(转)
    ThinkPHP+jQuery EasyUI Datagrid查询数据的简单处理
    ThinkPHP学习(三)
    Apache+PHP配置PATHINFO的一个小问题
    ThinkPHP学习(二)
    接口签名工具类
    RSA加密和解密工具类
    kafka项目中踩到的一个坑(客户端和服务器端版本不一致问题)
    自己实现字符串转整数(不使用JDK的字符串转整数的方法)
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7608372.html
Copyright © 2020-2023  润新知