zoukankan      html  css  js  c++  java
  • 【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;
    }
    


  • 相关阅读:
    剑指Offer——对成的二叉树
    剑指Offer——二叉树的下一个节点
    路径总和I、II、III
    性能调优工具
    关于在程序中内存检测的一些知识
    ptmalloc、tcmalloc及 jemalloc总结
    [LeetCode] 43. 字符串相乘
    [LeetCode] 155. Min Stack
    [LeetCode] 380. Insert Delete GetRandom O(1)
    linux内存过高排查
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9794008.html
Copyright © 2011-2022 走看看