zoukankan      html  css  js  c++  java
  • uva 10069 Distinct Subsequences(高精度 + DP求解子串个数)

    题目连接:10069 - Distinct Subsequences


    题目大意:给出两个字符串x (lenth < 10000), z (lenth < 100), 求在x中有多少个z。


    解题思路:二维数组DP, 有类似于求解最长公共子序列, cnt[i][j]表示在x的前j个字符中有多少个z 前i个字符。

    状态转移方程  

    1、x[j] != z[i]              cnt[i][j] = cnt[i][j - 1];

    2、x[j] == z[i]   cnt[i][j] = cnt[i][j - 1] + cnt[i - 1][j - 1];

    计算的时候使用高精度, 并且要见j == 0的情况归1, i == 0 的情况归0。


    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    using namespace std;
    const int N = 10005;
    const int M = 105;
    
    struct bign {
        int len, sex;
        int s[M];
    
        bign() {
    	this -> len = 1;
    	this -> sex = 0;
    	memset(s, 0, sizeof(s));
        }
    
        bign operator = (const char *number) {
    	int begin = 0;
    	len = 0;
    	sex = 1;
    	if (number[begin] == '-') {
    	    sex = -1;
    	    begin++;
    	}
    	else if (number[begin] == '+')
    	    begin++;
    
    	for (int j = begin; number[j]; j++)
    	    s[len++] = number[j] - '0';
        }
    
        bign operator = (int number) {
    	char string[N];
    	sprintf(string, "%d", number);
    	*this = string;
    	return *this;
        }
    
        bign (int number) {*this = number;}
        bign (const char* number) {*this = number;}
    
        bign change(bign cur) {
    	bign now;
    	now = cur;
    	for (int i = 0; i < cur.len; i++)
    	    now.s[i] = cur.s[cur.len - i - 1];
    	return now;
        }
    
        void delZore() {	// 删除前导0.
    	bign now = change(*this);
    	while (now.s[now.len - 1] == 0 && now.len > 1) {
    	    now.len--;
    	}
    	*this = change(now);
        }
    
        void put() {    // 输出数值。
    	delZore();
    	if (sex < 0 && (len != 1 || s[0] != 0))
    	    cout << "-";
    	for (int i = 0; i < len; i++)
    	    cout << s[i];
        }
    
        bign operator + (const bign &cur){  
    	bign sum, a, b;  
    	sum.len = 0;
    	a = a.change(*this);
    	b = b.change(cur);
    
    	for (int i = 0, g = 0; g || i < a.len || i < b.len; i++){  
    	    int x = g;  
    	    if (i < a.len) x += a.s[i];  
    	    if (i < b.len) x += b.s[i];  
    	    sum.s[sum.len++] = x % 10;  
    	    g = x / 10;  
    	}  
    	return sum.change(sum);  
        } 
    };
    
    bign cnt[M][N], sum;
    char x[N], z[M];
    
    int main() {
        int cas;
        scanf("%d", &cas);
        while (cas--) {
    	scanf("%s%s", x, z);
    	int n = strlen(x), m = strlen(z);
    	for (int i = 0; i <= n; i++)
    	    cnt[0][i] = 1;
    
    	for (int i = 1; i <= m; i++) {
    	    cnt[i][0] = 0;
    	    for (int j = 1; j <= n; j++) {
    		cnt[i][j] = cnt[i][j - 1];
    		if (z[i - 1] == x[j - 1])   
    		    cnt[i][j] = cnt[i][j] + cnt[i - 1][j - 1];
    	    }
    	}
    	cnt[m][n].put();
    	printf("
    ");
        }
        return 0;
    }
    


  • 相关阅读:
    《JAVA设计模式》之责任链模式(Chain of Responsibility)
    《JAVA设计模式》之迭代器模式(Iterator)
    《JAVA设计模式》之观察者模式(Observer)
    【python】effective python读书笔记
    【python】contextlib的使用
    【linux】乱七八糟命令
    【深度学习】使用Ray
    【深度学习】超参调节方式:Bayesian Opt
    【linux】scp不需要输入密码的方法
    【深度学习】论文TCN
  • 原文地址:https://www.cnblogs.com/james1207/p/3304036.html
Copyright © 2011-2022 走看看