「TJOI 2018」碱基序列

传送门


problem

小豆参加了生物实验。在实验室里,他主要研究蛋白质。他现在研究的蛋白质是由 k k k 个氨基酸按一定顺序构成的。每一个氨基酸都可能有 a a a 种碱基序列 s i , j s_{i,j} si,j 构成。

现在小豆有一个碱基串 s s s,小豆想知道在这个碱基上都多少中不同的组合方式可能得到这个蛋白质。即求由 k k k 段字符串有序合并成的字符串 s 1 s_1 s1,有多少种不同方式能够匹配字符串 s s s,其中 k k k 段字符串的选法不同,或者与 s s s 匹配上的位置不同认为是不同的方式。

数据范围: 1 ≤ k ≤ 100 1\leq k\leq100 1k100 ∣ s ∣ ≤ 10000 |s|\leq10000 s10000 a i ≤ 10 a_i\leq10 ai10

PS:这题的题描有点模糊,可以参考一下样例及样例解释。


solution

这道题其实挺简单的。

f i , j f_{i,j} fi,j 表示前 i i i 个串组成的字符串,与字符串 s s s 的前 j j j 个字符匹配的方案。

转移很简单,用 hash 判一下字符串匹配,然后暴力转移就可以了。代码也很好写。

时间复杂度 O ( ∣ s ∣ ∑ a i ) O(|s|\sum a_i) O(sai)


code

#include<bits/stdc++.h>
#define ull unsigned long long
using namespace std;
const int N=1e4+5,P=1e9+7;
int n,k,f[105][N];
ull b=131,Pow[N],Hash[N];
void Add(int &x,int y)  {x=(x+y>=P)?x+y-P:x+y;}
char S[N],T[N];
void prework(){
	Pow[0]=1;
	for(int i=1;i<=n;++i)  Pow[i]=Pow[i-1]*b;
	for(int i=1;i<=n;++i)  Hash[i]=Hash[i-1]*b+S[i]-'A'+1;
}
ull Get(int l,int r){
	return Hash[r]-Hash[l-1]*Pow[r-l+1];
}
int main(){
	scanf("%d%s",&k,S+1);
	n=strlen(S+1),prework();
	for(int i=0;i<=n;++i)  f[0][i]=1;
	for(int i=1,num,L;i<=k;++i){
		scanf("%d",&num);
		while(num--){
			ull now=0;
			scanf("%s",T+1),L=strlen(T+1);
			for(int j=1;j<=L;++j)  now=now*b+T[j]-'A'+1;
			for(int j=L;j<=n;++j)
				if(Get(j-L+1,j)==now)  Add(f[i][j],f[i-1][j-L]);
		}
	}
	int ans=0;
	for(int i=1;i<=n;++i)  Add(ans,f[k][i]);
	printf("%d\n",ans);
	return 0;
}
在MATLAB中,要从碱基序列(通常是DNA或RNA序列)的功率谱中获取信噪比,首先需要将碱基序列转换成时间序列(如二进制脉冲序列),然后进行傅立叶变换。假设我们有一个DNA序列(以'A'、'C'、'G'、'T'编码),我们可以按照以下步骤操作: 1. **碱基序列转二进制序列**: ```matlab % 假设碱基序列 dna_seq = 'ATCG'; % 转换为二进制(1代表'A'或'C', 0代表'G'或'T') binary_seq = double(baseToBinary(dna_seq)); ``` 这里需要自定义`baseToBinary`函数来实现碱基转换,这取决于具体的映射规则。 2. **创建时间序列**: ```matlab % 将二进制序列展平为行向量 time_series = reshape(binary_seq, [], 1); % 确定序列长度 seq_length = size(time_series, 1); ``` 3. **计算功率谱**: ```matlab % 计算功率谱(假设是连续时间序列) psd = abs(fft(time_series, seq_length)) ./ (seq_length / 2); ``` 4. **找到1/3 Hz信号位置**: ```matlab fs = 1; % 根据实际情况设置采样率,此处假设是每秒1个样本 freqs = (0:seq_length/2-1) / fs; % 采样频率范围 signal_freq_idx = find(abs(freqs - 1/3) < tol); % tol是个小阈值,寻找1/3 Hz附近的数据 ``` 5. **计算信噪比**: ```matlab % 噪声估计:通常可以选取高于信号频率处的平均值作为背景噪声 noise_power = mean(psd(signal_freq_idx + 1:end)); % 高于信号频率部分的均值 signal_power = psd(signal_freq_idx); snr_db = 10 * log10(signal_power / noise_power); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值