• 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 }

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

  • 相关阅读:
    C语言之数据类型(int float double char unsigned )
    c语言的第一个程序
    socket之udp服务器和客户端
    页面置换算法的模拟实现 C
    C算法--入门篇(1)图形输出
    C算法--入门篇(1)查找元素
    C算法--入门篇(1)入门模拟2
    C算法--入门篇(1)入门模拟1
    C算法--黑盒测试
    C算法--复杂度
  • 原文地址:https://www.cnblogs.com/windrises/p/4783501.html
Copyright © 2020-2023  润新知