zoukankan      html  css  js  c++  java
  • 洛谷 P2679 子串

    题目传送门

    解题思路:

    f[i][j][p][0/1]表示B前j个字符由A的前i个字符分成p段,且A[i]选或不选的方案数.

    一.当B[j] == A[i]时:

    1.选A[i]时分三种情况 :

    (1)当前A[i-1]可以不选 f[i-1][j-1][p-1][0]

    (2)当前A[i]与A[i-1]在同一段上 f[i-1][j-1][p][1]

    (3)当前A[i]与A[i-1]不在同一段上 f[i-1][j-1][p-1][1]

    2.不选A[i]时,分两种情况:

    (1)A[i-1]选 f[i-1][j][p][1]

    (2)A[i-1]不选 f[i-1][j][p][0]

    二.当B[j]==A[i]时:

    1.选A[i] : f[i][j][p][1]=0;

    2.不选A[i]同上

    好了,这道题的思路就是这样了,但是还有一点需要注意,如果直接写上面的方程的话,会MLE,然后又发现可以压一维,然后就AC了.

    //别忘了初始化.

    还有最重要的一点:代码第3行的三个人排名不分先后!!!!

    先贴一下思路中的未经优化的代码,便于理解:

     1 #include<iostream>
     2 #include<cstdio>
     3 
     4 using namespace std;
     5 
     6 string a,b;
     7 int n,m,w,f[1001][201][201][2];
     8 
     9 int main() {
    10     scanf("%d%d%d",&n,&m,&w);
    11     cin >> a >> b;
    12     for(int i = 0;i <= n; i++)
    13         f[i][0][0][0] = 1;
    14     for(int i = 1;i <= n; i++)
    15         for(int j = 1;j <= m; j++)
    16             for(int k = 1;k <= w; k++) {
    17                 if(a[i-1] == b[j-1]) {
    18                     f[i][j][k][1] = f[i-1][j-1][k-1][0] + f[i-1][j-1][k-1][1] + f[i-1][j-1][k][1];
    19                     f[i][j][k][0] = f[i-1][j][k][0] + f[i-1][j][k][1];
    20                 }
    21                 else {
    22                     f[i][j][k][1] = 0;
    23                     f[i][j][k][0] = f[i-1][j][k][0] + f[i-1][j][k][1];
    24                 }
    25             }
    26     printf("%d",f[n][m][w][1] + f[n][m][w][0]);
    27     return 0;
    28 }
    MLE+没有处理细节

    AC代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #define yyq_ljx_xhy 1000000007
     4 //排名不分先后,都可以吊打本蒟蒻 
     5 using namespace std;
     6 
     7 string a,b;
     8 int n,m,w,f[2][201][201][2],p;
     9 
    10 int main() {
    11     scanf("%d%d%d",&n,&m,&w);
    12     cin >> a >> b;
    13     f[1][0][0][0] = f[0][0][0][0] = 1;
    14     for(int i = 1;i <= n; i++,p ^= 1)
    15         for(int j = 1;j <= m; j++)
    16             for(int k = 1;k <= w; k++) {
    17                 if(a[i-1] == b[j-1]) {
    18                     f[p][j][k][1] = (f[p^1][j-1][k-1][0] + (f[p^1][j-1][k-1][1] + f[p^1][j-1][k][1]) % yyq_ljx_xhy) % yyq_ljx_xhy; 
    19                     //这里一定要%两次,否则会WA,这说明一个道理,做不出题来,%一下大佬就做出来了 
    20                     f[p][j][k][0] = (f[p^1][j][k][0] + f[p^1][j][k][1]) % yyq_ljx_xhy; 
    21                 }
    22                 else {
    23                     f[p][j][k][1] = 0;
    24                     f[p][j][k][0] = (f[p^1][j][k][0] + f[p^1][j][k][1]) % yyq_ljx_xhy;
    25                 }
    26             }
    27     printf("%d",(f[p^1][m][w][1] + f[p^1][m][w][0]) % yyq_ljx_xhy);
    28     return 0;
    29 }

    //NOIP2015提高 Day2 T2

  • 相关阅读:
    蓝桥杯历届试题 打印十字图 文字图形
    Cuckoo Hashing
    2006 飞行员配对(二分图最大匹配)
    Bad Hair Day(求数组中元素和它后面离它最近元素之间的元素个数)
    2019CCPC江西省赛
    字典树系统学习
    ac自动机学习
    项目管理(把与某点相邻边分为两类 是复杂度降为(n^(3/2))
    Ultra-QuickSort(离散化)
    Chika and Friendly Pairs(莫队+树状数组+离散化+预处理上下界)
  • 原文地址:https://www.cnblogs.com/lipeiyi520/p/12339851.html
Copyright © 2011-2022 走看看