syhd142  
日历
<2024年5月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678
统计
  • 随笔 - 23
  • 文章 - 122
  • 评论 - 31
  • 引用 - 0

导航

常用链接

留言簿(2)

随笔档案(23)

文章分类(270)

文章档案(122)

我的豆瓣

搜索

  •  

最新评论

阅读排行榜

评论排行榜

 
题意:在一个母串X中找出字串Z出现的最大次数。
解法:很明显的DP;状态表示:用a[i][j]表示字串的前i个在母串的前j个中出现得最大次数;转移方程:始终有a[i][j] = a[i][j-1],因为字串前i个在母串前j-1个中出现的次数显然也会在母串前j个出现,当x[j]==z[i]时,还要加上字串前i-1个在母串前j-1个出现的次数。可以转化为一维的,具体见代码:
#include<iostream>
#include
<algorithm>
using namespace std;
#define Base 1000000000
#define Cap 30
typedef 
long long hugeint;

struct bignum
{
    
int Len;
    
int Data[Cap];
    bignum() : Len(
0){}
    bignum(
const bignum &V) : Len(V.Len)
    {
        memcpy(Data,V.Data,Len 
* sizeof*Data);
    }
    bignum(
int V) : Len(0)
    {
        
for(;V > 0;V /= Base)
        Data[Len
++= V % Base;
    }
    bignum 
&operator = (const bignum &V)
    {
        Len 
= V.Len;
        memcpy(Data,V.Data,Len 
* sizeof*Data);
        
return *this;
    }
    
int &operator[](int Index) 
    {
        
return Data[Index];
    }
    
int operator[](int Index) const
    {
        
return Data[Index];
    }
};

bignum 
operator+(const bignum &A, const bignum &B)
{
    bignum R;
    
int i;
    
int Carry = 0;
    
for(i = 0; i < A.Len || i < B.Len || Carry > 0; i++)
    {
        
if(i < A.Len)
            Carry 
+= A[i];
        
if(i < B.Len)
            Carry 
+= B[i];
        R[i] 
= Carry % Base;
        Carry 
/= Base;
    }
    R.Len 
= i;
    
return R;
}

ostream
& operator<<(ostream &Out, const bignum &V)
{
    
int i;
    Out 
<< (V.Len == 0 ? 0 : V[V.Len - 1]);
    
for(i = V.Len - 2; i >= 0; i--)
    
for(int J = Base / 10; J > 0; J /= 10)
        Out 
<< V[i] / J % 10;
    
return Out;
}

#define M 105
#define N 10005

bignum d[M];
char s1[N], s2[M];

int main()
{
    
int t, l1, l2;
    scanf(
"%d"&t);
    
while(t--)
    {
        scanf(
"%s %s"&s1, &s2);
        l1 
= strlen(s1), l2 = strlen(s2);
        
for(int i = 1; i <= l2; i++) d[i] = bignum(0);
        d[
0= bignum(1);
        
for(int i = 1; i <= l1; i++)
        
for(int j = l2; j >= max(l2 - l1 + i, 1); j--)
        {
            
if(s1[i - 1== s2[j - 1])
            {
                d[j] 
= d[j] + d[j - 1];
            }
        }
        cout 
<<d[l2]<<endl;
    }
    
return 0;
}
posted on 2010-06-14 16:43 Fucker 阅读(1928) 评论(4)  编辑 收藏 引用 所属分类: ACM/ICPCDP
评论:
  • # re: UVA 10069 Distinct Subsequences  Yip Posted @ 2010-08-19 14:24
    这个题解能详细点吗?
    我不太明白为什么 始终有a[i][j] = a[i][j-1]
    状态转移方程好像不太清楚怎么弄出来的额  回复  更多评论   

  • # re: UVA 10069 Distinct Subsequences  沙茶 Posted @ 2010-09-23 21:44
    请问为什么“scanf("%s %s", &s1, &s2); ”和“scanf("%s %s", s1, s2);”等价?  回复  更多评论   

  • # re: UVA 10069 Distinct Subsequences  Fucker Posted @ 2010-09-24 10:08
    @沙茶
    因为s1和s2是字符串首地址,所以加不加&都是一样的。  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


 
Copyright © Fucker Powered by: 博客园 模板提供:沪江博客