DNA Regions

 设X 为字符不同的位数, Y为字符相同的位数,则限制条件可以表示为X/(X+Y) < p/100

X*100 < X*p+Y*p 移项后可得  Y*p+X*(p-100) > 0,建立一个数组arr,如果第i位的字符相同则arr[i]赋值为p,如果不相同赋值为p-100,则题目的要求可以变为在该数组中找出最长的子串是得子串的和大于等于0

jump[i]表示从i+1开始的最大和(>= 0)连续序列的结尾下标可以同过O(n)的递推求出,

从运行时间来看时间复杂度应该接近O(n)。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cctype>
#include <utility>   
#include <map>
#include <string>  
#include <climits> 
#include <set>
#include <string> 
#include <sstream>
#include <utility>
#include <ctime>
 
using std::priority_queue;
using std::vector;
using std::swap;
using std::stack;
using std::sort;
using std::max;
using std::min;
using std::pair;
using std::map;
using std::string;
using std::cin;
using std::cout;
using std::set;
using std::queue;
using std::string;
using std::istringstream;
using std::make_pair;
using std::greater;

const int MAXN(150010);

int n, p;
char str1[MAXN], str2[MAXN];
int sum[MAXN], jump[MAXN];

void run()
{
	sum[0] = 0;
	for(int i = 1; i <= n; ++i)
	{
		if(str1[i] == str2[i])
			sum[i] = sum[i-1]+p;
		else
			sum[i] = sum[i-1]+p-100;
	}
	jump[n] = n;
	for(int i = n-1; i >= 1; --i)
	{
		if(sum[jump[i+1]]-sum[i] < 0)
			jump[i] = i;
		else
			jump[i] = jump[i+1];
	}
	int ans = 0; 
	for(int i = 1; i <= n; ++i)
	{
		int ts = 0, loc = i;
		while(loc <= n)
		{
			if(ts+sum[jump[loc]]-sum[loc-1] < 0)
				break;
			ts += sum[jump[loc]]-sum[loc-1];
			loc = jump[loc]+1;
		}
		ans = max(ans, loc-i);
	}
	if(ans)
		printf("%d\n", ans);
	else
		printf("No solution.\n");
}

int main()
{
	while(scanf("%d%d", &n, &p), n)
	{
		scanf("%s%s", str1+1, str2+1);
		run();
	}
	return 0;
}


你可能感兴趣的:(DNA Regions)