zoukankan      html  css  js  c++  java
  • LightOJ1013 Love Calculator(DP)

    容易猜测到包含s1、s2序列的串的最短长度是LCS(s1,s2) + ( len(s1) - LCS(s1,s2) ) + ( len(s2) - LCS(s1,s2) ) ,即:

    len(s1)+len(s2)-LCS(s1,s2)

    接下来求方案数,可以想到:

    dp[k][i][j]表示由s1前i位和s2前j位的序列构成的长度为k的串的方案数

    dp[k][i][j]是由dp[k-1][i-1][j]、dp[k-1][i][j-1]和dp[k-1][i-1][j-1]转移的,而从dp[k-1][i-1][j-1]转移则要满足s1[i]==s2[j]的条件。

    转移方程我纠结了好久,才“试”出来:

    dp[k][i][j] = (s1[i]==s2[j]) ? dp[k-1][i-1][j-1] : dp[k-1][i-1][j]+dp[k-1][i][j-1]

    然后因为自己想的一个数据s1="aa",s2="ab"又纠结了好久,才“试”出初始状态是:

    d[1][1][0]=d[1][0][1]=1

    (s1[1]==s2[1]) ? d[1][1][1]=1 : d[1][1][1]=0

    最后提交就AC了,有点不明觉厉。。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 int LCS[33][33];
     6 long long d[66][33][33];
     7 int main(){
     8     int t;
     9     char s1[33],s2[33];
    10     scanf("%d",&t);
    11     for(int cse=1; cse<=t; ++cse){
    12         scanf("%s%s",s1+1,s2+1);
    13 
    14         int l1=strlen(s1+1),l2=strlen(s2+1);
    15         memset(LCS,0,sizeof(LCS));
    16         for(int i=1; i<=l1; ++i){
    17             for(int j=1; j<=l2; ++j){
    18                 if(s1[i]==s2[j]) LCS[i][j]=LCS[i-1][j-1]+1;
    19                 else LCS[i][j]=max(LCS[i-1][j],LCS[i][j-1]);
    20             }
    21         }
    22         int len=l1+l2-LCS[l1][l2];
    23 
    24         memset(d,0,sizeof(d));
    25         d[1][1][0]=d[1][0][1]=1;
    26         if(s1[1]==s2[1]) d[1][1][1]=1;
    27         for(int k=2; k<=len; ++k){
    28             for(int i=0; i<=l1; ++i){
    29                 for(int j=0; j<=l2; ++j){
    30                     if(i==0 && j==0) continue;
    31                     if(i==0) d[k][i][j]=d[k-1][i][j-1];
    32                     else if(j==0) d[k][i][j]=d[k-1][i-1][j];
    33                     else if(s1[i]==s2[j]) d[k][i][j]=d[k-1][i-1][j-1];
    34                     else d[k][i][j]=d[k-1][i-1][j]+d[k-1][i][j-1];
    35                 }
    36             }
    37         }
    38 
    39         printf("Case %d: %d %lld
    ",cse,len,d[len][l1][l2]);
    40     }
    41     return 0;
    42 }
  • 相关阅读:
    浅谈生成全排列的4种方法
    UVA
    UVA
    UVA
    UVA
    MySQL索引篇
    MySQL事务篇
    MySQL架构篇
    Redis性能调优
    Redis分布式锁
  • 原文地址:https://www.cnblogs.com/WABoss/p/5115564.html
Copyright © 2011-2022 走看看