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

来源:互联网 发布:个人网站域名后缀 编辑:程序博客网 时间:2024/05/20 19:47
/*强力推荐:五星,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 TESTcout<<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 TESTcout<<i<<" "<<j<<" "<<d[i][j]<<endl;#endif}}cout<<d[0][0]<<endl;}return 0;}

原创粉丝点击