hdu 4295 4 substrings problem

4 substrings problem

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 442    Accepted Submission(s): 148


Problem Description
  One day you heard the following joke
     In America, you write strings.
    In Soviet Russia, String writes YOU!!
1
  And find that now string is writting you! So to get rid of it, you must solve the following problem:
  Given a string S and its four substring a,b,c, and d. In a configuration, you can place four substrings exactly one position it occurs in S (they may overlap), and characters covered by at least one such substring is called “covered”.
  You should solve for minimum and maximum possible number of covered characters in a configuration.
  You may assume that s contains only lowercase letters, and is of length less than 4096. However, lengths of a,b,c, and d would never exceed 64.
-------------------------------------------------------------------
1An infamous Russian reversal
 

Input
  There are several test cases.
  For each test case there are 5 lines, denoting S,a,b,c, and d, respectively.
  Please process until the EOF (End Of File).
 

Output
  For each test case, please print a single line with two integers, first the minimum, then the maximum.
 

Sample Input
  
  
hello he l l o abacaba ab ba a c
 

Sample Output
  
  
4 5 4 6
 

Source


代码:(比较低效)
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=4100;
char s[N],ss[70];
short l,sl[4],maxl;
short flag[N],d1[N][16][65],d2[N][16][65];
int main()
{
	int i,j,k,x;
	while(~scanf("%s",s))
	{
		l=strlen(s);
		memset(flag,0,sizeof(flag[0])*l);
		for(i=0;i<4;i++)
		{
			scanf("%s",ss);
			sl[i]=strlen(ss);
			for(j=0;j+sl[i]<=l;j++)
			{
				for(k=0;ss[k];k++)if(s[j+k]!=ss[k])break;
				if(ss[k]=='\0') flag[j]|=1<<i;
			}
			if(sl[i]>maxl) maxl=sl[i];
		}
		memset(d1,0x3f,sizeof(d1[0])*(l+1));
		memset(d2,0xc3,sizeof(d1[0])*(l+1));
		d1[0][0][0]=d2[0][0][0]=0;
		for(i=0;i<l;i++)for(j=0;j<16;j++)for(k=0;k<=maxl;k++)
		{
			d1[i+1][j][k?k-1:0]=min(d1[i][j][k],d1[i+1][j][k?k-1:0]);
			d2[i+1][j][k?k-1:0]=max(d2[i][j][k],d2[i+1][j][k?k-1:0]);
			for(x=0;x<4;x++)
			{
				if((1<<x&~j)&&(1<<x&flag[i]))
				{
					short t=max((short)k,sl[x]);
					d1[i][1<<x|j][t]=min((short)(d1[i][j][k]+t-k),d1[i][1<<x|j][t]);
				    d2[i][1<<x|j][t]=max((short)(d2[i][j][k]+t-k),d2[i][1<<x|j][t]);
				}
			}
		}
		printf("%hd %hd\n",d1[l][15][0],d2[l][15][0]);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值