10069 - Distinct Subsequences(高精度+动态规划)

/*
强力推荐:五星,WA!!!

首先要用到高精度处理。
动态规划的使用这里有点小问题,原来我的想法,d[i][j]表示line1从i和line2从j开始的不同子序列个数。d[i][j]=sum{d[i+1][k] | k属于(j,len2)}。状态有len1*len2种,状态转移有len2种。

另一种解法:d[i][j]=d[i][j+1];if(line1[i]==line2[j]) d[i][j]+=d[i+1][j+1];这样可将状态转移优化为O(1)种。

题意:不同的子序列。字符串line1和line2,求line1的子序列中为line2的个数。
*/

//如果使用递归,使用visit[]来标记是否查找过即可

//#define TEST
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
struct BigNumber
{
	int data[110];
	int len;
	BigNumber(){len=1;data[0]=0;}
	BigNumber(int a){*this=a;}
	BigNumber operator=(char a[]);
	BigNumber operator=(int a);
	BigNumber operator+(BigNumber &a);
	friend ostream & operator<<(ostream &out,BigNumber &a);
	void clearLeadZero();
};
void BigNumber::clearLeadZero()
{
	while(len>0 && data[len]==0)
		len--;
}
BigNumber BigNumber::operator=(char a[])
{
	len=strlen(a);
	for(int i=0;i<len;i++)
		data[i]=a[len-1-i]-'0';
	return *this;
}
BigNumber BigNumber::operator=(int a)
{
	char s[20];
	sprintf(s,"%d",a);
	*this=s;
	return *this;
}
BigNumber BigNumber::operator+(BigNumber &a)
{
	int i;
	int p=0;
	BigNumber c;
	for(i=0;p || i<len || i<a.len;i++)
	{
		if(i<len) p+=data[i];
		if(i<a.len) p+=a.data[i];
		c.data[i]=p%10;
		p/=10;
	}
	c.len=i;
	c.clearLeadZero();
	return c;
}
ostream & operator<<(ostream &out,BigNumber &a)
{
	for(int i=a.len-1;i>=0;i--)
		out<<a.data[i];
	return out;
}
const int nMax1=10010,nMax2=110;
BigNumber d[nMax1][nMax2];
char line1[nMax1],line2[nMax2];
int len1,len2;
int N;
void init()
{
	gets(line1);
	gets(line2);
	len1=strlen(line1);
	len2=strlen(line2);
	for(int i=0;i<=len1;i++)
		for(int j=0;j<=len2;j++)
			d[i][j]=0;
	int p=0;
	for(int i=len1-1;i>=0;i--)
	{
		if(line1[i]==line2[len2-1])
			++p;
		d[i][len2-1]=p;
#ifdef TEST
				cout<<i<<" "<<len2-1<<" "<<d[i][len2-1]<<endl;
#endif
	}
}
int main()
{
	freopen("f://data.in","r",stdin);
	scanf("%d",&N);
	getchar();
	while(N--)
	{
		init();
		for(int j=len2-2;j>=0;j--)
		{
			for(int i=len1-(len2-j);i>=0;i--)
			{
				d[i][j]=d[i+1][j];
				if(line1[i]==line2[j])
					d[i][j]=d[i][j]+d[i+1][j+1];
#ifdef TEST
				cout<<i<<" "<<j<<" "<<d[i][j]<<endl;
#endif
			}
		}

		cout<<d[0][0]<<endl;
	}
	return 0;
}

你可能感兴趣的:(10069 - Distinct Subsequences(高精度+动态规划))