卡了我一天的题我还能说是水题吗。。。。
开始的思路【半递推半搜索】虽然是不成熟的动规,但是我觉得至少还能过。
看了人家比较成熟的思路却没有过。
但最后还是用成熟的动规思路过的。
代码挫在了写大数的地方。少了个等号,,,,
状态:d[i][j]表示子串的前i-1个字符在母串前j-1个位置中出现的次数
状态转移:(sub[i-1]==s[j-1])d[i][j] = d[i][j-1]; (sub[i-1]!=s[j-1]) d[i][j] = d[i][j-1]+d[i-1][j-1];
代码如下:
#include <cstdio> #include <cstring> #define M 10005 #define N 105 char s[M],sub[N]; int len,s_len,d[N][M][N],t[N] = {0}; void add(int* a,int* b) { for(int i = 0; i < N; i++) { a[i]+=b[i]; } for(int i = 0; i < N; i++) { if(a[i]>=10) { a[i]-=10; a[i+1]+=1; } } } void print_ans() { int f = 0; int *ans = d[s_len][len]; for(int i = N-1; i >= 0; i--) {if(ans[i]) f = 1; if(f)printf("%d",ans[i]); } printf("\n"); } int main () { int cas; t[0] = 1; scanf("%d",&cas);getchar(); while(cas--) { gets(s);gets(sub); len = strlen(s); s_len = strlen(sub); memset(d[1][0],sizeof(d[1][0])); for(int i = 1; i <= len; i++) { memcpy(d[1][i],d[1][i-1],sizeof(d[i][i-1])); if(sub[0]==s[i-1]) add(d[1][i],t); } for(int i = 2; i <= s_len; i++) { for(int j = i; j <= len; j++) { memcpy(d[i][j],d[i][j-1],sizeof(d[i][j-1])); if(s[j-1]==sub[i-1]) add(d[i][j],d[i-1][j-1]); } } print_ans(); } return 0; }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。