• 【NOIP2015提高组T5】子串-字符串上的动态规划


    (本人本题完成于2016-7-22)

    题目:子串-题目

    做法:设f[i][j][k]为在A串前i个字符中分k份取出B串前j个字符的方案数,再设一个数组g[i][j][k]为在A串前i个字符中分k份取出B串前j个字符,其中必取A串的第i个字符的方案数,由此得到状态转移方程:

    g[i][j][k]=f[i-1][j-1][k-1]+g[i-1][j-1][k] (A[i]=B[j])

    g[i][j][k]=0 (A[i]≠B[j])

    f[i][j][k]=f[i-1][j][k]+g[i][j][k]

    由于数据较大,所以我们可以以i划分阶段,用滚动数组存储,可以大大节省空间。

    以下是本人代码:

    #include <cstdio>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define mod 1000000007
    using namespace std;
    long n,m,K,f[2][210][210]={0},g[2][210][210]={0},now,past; //使用滚动数组,节省空间
    char a[1010],b[210]; //存储A串和B串
    
    int main()
    {
      scanf("%ld %ld %ld
    ",&n,&m,&K);
      for(int i=1;i<=n;i++) scanf("%c",&a[i]);
      scanf("
    ");
      for(int i=1;i<=m;i++) scanf("%c",&b[i]);
      
      f[0][0][0]=1; //初始化
      now=1;past=0;
      for(int i=1;i<=n;i++)
      {
        f[now][0][0]=1;
        for(int j=1;j<=m;j++)
    	  for(int k=1;k<=K;k++)
    	  {
    	    if (a[i]==b[j]) g[now][j][k]=(f[past][j-1][k-1]+g[past][j-1][k])%mod;
    		else g[now][j][k]=0;
    		f[now][j][k]=(f[past][j][k]+g[now][j][k])%mod;
    	  }
    	int t=now;now=past;past=t;
      }
      
      printf("%ld",f[past][m][K]%mod);
      
      return 0;
    }
    


  • 相关阅读:
    一般图最大匹配
    UOJ164 线段树历史最值查询
    一个经典的排列组合面试题目
    动态代理理解
    JAVA nio
    hadoop NameNode 实现分析
    以一个上传文件的例子来说 DistributedFileSystem
    hadoop IPC 源代码分析
    hadoop DataNode实现分析
    HDFS 整体把握
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9794009.html
Copyright © 2020-2023  润新知