洛谷 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

 

posted @ 2020-02-21 00:02  Mr^Simon  阅读(112)  评论(0编辑  收藏  举报