UVa-1625

  这道题我硬是做了两天多。dp比较好写,但是预处理很难写。自己第一次没写出来,看lrj的,结果反而越看越发愣。但还是受了点启发,改用c[i][j]来表示第一个字符串拿出前i个,第二个字符串拿出前j个时有多少种字母是已经开始了,但还没有结束。

  然后又因为memset而超时了,学到的教训就是如果大部分数据范围比较小,还是不要用memset初始化。先读入数据范围,再手写for循环初始化。从超时的3s到AC的0s,这差距还是挺大的!然后时间得到了rank 5!

  lrj貌似是用滚动数组做的,他的c数组的计算还是和dp一起进行的,很难看懂。。。。(我已经弃疗了)

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 using namespace std;
 5 const int inf=0x3f3f3f3f;
 6 const int maxn=5005;
 7 char a[maxn],b[maxn];
 8 int len1,len2;
 9 int first[255][3],last[255][3];
10 int dp[maxn][maxn];
11 int c[maxn][maxn];
12 int main()
13 {
14     int T;
15     scanf("%d",&T);
16     for(int kase=1;kase<=T;++kase)
17     {
18         scanf("%s%s",a+1,b+1);
19         len1=strlen(a+1),len2=strlen(b+1);
20         for(int i='A';i<='Z';i++)
21         {
22             first[i][1]=first[i][2]=inf;
23             last[i][1]=last[i][2]=-1;
24         }
25         for(int i=0;i<=len1;i++)
26             for(int j=0;j<=len2;j++)
27             c[i][j]=dp[i][j]=0;
28         for(int i=1;i<=len1;i++)
29         {
30             if(first[a[i]][1]==inf) first[a[i]][1]=i;
31             last[a[i]][1]=i;
32         }
33         for(int i=1;i<=len2;i++)
34         {
35             if(first[b[i]][2]==inf) first[b[i]][2]=i;
36             last[b[i]][2]=i;
37         }
38         for(int i=0;i<=len1;i++)
39         {
40             if(i)
41             {
42                 c[i][0]=c[i-1][0];
43                 if(first[a[i]][1]==i) c[i][0]++;
44                 if(last[a[i]][1]==i&&last[a[i]][2]==-1) c[i][0]--;
45             }
46             for(int j=1;j<=len2;j++)
47             {
48                 c[i][j]=c[i][j-1];
49                 if(first[b[j]][2]==j&&first[b[j]][1]>i) c[i][j]++;
50                 if(last[b[j]][2]==j&&last[b[j]][1]<=i) c[i][j]--;
51             }
52         }
53         for(int i=0;i<=len1;i++)
54             for(int j=0;j<=len2;j++)
55             {
56                 if(i>0&&j>0) dp[i][j]=min(dp[i-1][j],dp[i][j-1])+c[i][j];
57                 else if(i==0&&j>0) dp[i][j]=dp[i][j-1]+c[i][j];
58                 else if(i>0&&j==0) dp[i][j]=dp[i-1][j]+c[i][j];
59             }
60         printf("%d
",dp[len1][len2]);
61     }
62 }

 自己做题的效率一直比较低,这几天忙着迎新和一些学生工作,时间碎片化了。然而这学期学生工作比较多。。。

原文地址:https://www.cnblogs.com/windrises/p/4783501.html