TopCoder SRM 599 Div2 950 SimilarNames2

本文深入探讨了一种暴力匹配算法,用于计算字符串前缀的数量,并基于此解决特定排列问题。通过预处理每个单词的前缀数量,算法能快速计算在限定位置下的方案数,最后部分采用乱排策略。代码示例使用C++实现,包括组合数计算和模板函数优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

暴力求出每个单词的前缀数量f[i]f[i]
那么如果我们要将这个单词排在第LL位,前L1位的方案数就是(f[i]1L1)(f[i]−1L−1),然后最后nLn−L位就乱排。

#include <bits/stdc++.h>
using namespace std;
const int N=51;
const int p=1e9+7;
int n,f[N],C[N][N];

template<class T> void checkmin(T &a,const T &b) { if (b<a) a=b; } 
template<class T> void checkmax(T &a,const T &b) { if (b>a) a=b; }

class SimilarNames2 {
public:
    int count( vector <string> names, int L ) ;
};

int cmp(const string a,const string b){
    return a.size()<b.size();
}

int pd(string a,string b){
    for(int i=0;i<a.size();i++)
     if (a[i]!=b[i]) return 0;
    return 1;
}

void init(){
    for(int i=0;i<N;i++) C[i][0]=1;
    for(int i=1;i<N;i++)
     for(int j=1;j<=i;j++)
      C[i][j]=(C[i-1][j]+C[i-1][j-1])%p;
}

int SimilarNames2::count(vector <string> a, int L) {
    init();
    n=a.size();
    sort(a.begin(),a.end(),cmp);
    for(int i=0;i<n;i++){
        f[i]=1;
        for(int j=i-1;j>=0;j--)
         if (pd(a[j],a[i])){
            f[i]+=f[j];
            break;
         }
    }
    int ans=0;
    for(int i=0;i<n;i++)
     if (f[i]>=L) ans=(ans+C[f[i]-1][L-1])%p;
    for(int i=1;i<=n-L;i++) ans=1LL*ans*i%p;
    return ans;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值