UVa Problem 10069 Distinct Subsequences

最近学习DP。

本题题意是给你两个字符串x和z.

问你在x中有多少个z.可以简单的DP加上递推。对与a[i][j]代表长度j个母串中,出现多少个长度为i个子串。

如果第i个字母和j个字母不相同,则可以转化为a[i][j]=a[i][j-1];可以理解为长度为i的子串在长度为j的母串和长度为j-1的母串出现次数相同。

如果第i个字母和j个字母相同,这可以转化为a[i][j]=a[i][j-1]+a[i-1][j-1];理解为加上i-1的子串在j-1的子串出现次数。

初始化a[0][0]~a[0][s1.length()]为1,即0长度的子串在0的母串中出现次数为1。

子串长度100,母串10000,最多次数10的100次方,用java大数。

首先自己想到了二维数组

import java.io.BufferedInputStream;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Scanner;

public class Main {
   static BigInteger a[][]=new BigInteger[101][10001];
	public static void main(String[] args) {
		Scanner  cin=new Scanner (new BufferedInputStream(System.in));
		int n;String s1,s2;
		n=cin.nextInt();
		while(n-->0)
		{
		    s1=cin.next();s2=cin.next();
		    if(s1.length()<s2.length())
			System.out.println(0);
		    else 
		    {
			for(int i=0;i<=s2.length();i++)
			Arrays.fill(a[i], BigInteger.valueOf(0));
			for(int i=0;i<=s1.length();i++)
			a[0][i]=BigInteger.valueOf(1);

			for(int i=1;i<=s2.length();i++)
			    for(int j=1;j<=s1.length();j++)
			    {
				if(s1.charAt(j-1)==s2.charAt(i-1))a[i][j]=a[i][j-1].add(a[i-1][j-1]);
				else a[i][j]=a[i][j-1];
			    }
			System.out.println(a[s2.length()][s1.length()]);
			
		}
		}

	}
	public static int min(int length, int i) {
	    if(length>i)return i;
	    return length;
	}

}
然后,空间复杂度可以优化,应用滚动数组。

其实a[j]没被修改之前,存储就是i-1的a[j]。

import java.io.BufferedInputStream;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Scanner;

public class Main {
   static BigInteger a[]=new BigInteger[101];
	public static void main(String[] args) {
		Scanner  cin=new Scanner (new BufferedInputStream(System.in));
		int n;String s1,s2;
		n=cin.nextInt();
		while(n-->0)
		{
		    s1=cin.next();s2=cin.next();
		    if(s1.length()<s2.length())
			System.out.println(0);
		    else 
		    {
			Arrays.fill(a, BigInteger.valueOf(0));

			a[0]=BigInteger.valueOf(1);

			for(int i=1;i<=s1.length();i++)
			    for(int j=s2.length();j>=max(s2.length()-s1.length()+i,1);j--)
			    {
				if(s2.charAt(j-1)==s1.charAt(i-1))a[j]=a[j].add(a[j-1]);
			    }
			System.out.println(a[s2.length()]);		
		}
		}
	}
	public static int max(int length, int i) {
	    if(length<i)return i;
	    return length;
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值