HDU 1501 Zipper & ACM俱乐部 2604 单词混合

2014-11-24 02:39:43 · 作者: · 浏览: 1
分析:这两题都是一样的、输出有点细微的差别、如果直接暴力搜索的话、会TLE、于是我们需要强力的剪枝、记忆化搜索便是一个比较好的选择、重复的子问题只用计算一遍、大大的节省了结算时间、只需多开一个二维数组记录这个状态是否到达过便可以、当然动态规划也能做这题、毕竟记忆化搜索和动态规划是可以相互转化的可怜
#include  
#include  
int flag;  
int len1,len2,len3;  
const int maxn=205;  
char str1[maxn];  
char str2[maxn];  
char str3[maxn*2];  
int dp[maxn][maxn];  
void dfs(int x1,int x2,int x3){  
    if(x3>=len3){  
        flag=1;return;  
    }  
    if(flag==1)return;  
    if(dp[x1][x2])return;  
    if(str1[x1]==str3[x3]){  
        dfs(x1+1,x2,x3+1);  
    }  
    if(str2[x2]==str3[x3]){  
        dfs(x1,x2+1,x3+1);  
    }  
    dp[x1][x2]=1;  
}  
int main(){  
    int n;  
    int cas=1;  
    scanf("%d",&n);  
    while(n--){  
        memset(str1,'\0',sizeof(str1));  
        memset(str1,'\0',sizeof(str2));  
        memset(str1,'\0',sizeof(str3));  
        memset(dp,0,sizeof(dp));  
        scanf("%s%s%s",&str1,&str2,&str3);  
        len1=strlen(str1);  
        len2=strlen(str2);  
        len3=strlen(str3);  
        if(len1+len2!=len3){  
            printf("Case %d: no\n",cas++);  
            continue;  
        }  
        else{  
            flag=0;  
            dfs(0,0,0);  
            if(flag==0)printf("Case %d: no\n",cas++);  
            else printf("Case %d: yes\n",cas++);  
        }  
    }  
    return 0;  
}  

DP:
#include   
#include   
  
int main() {  
        int n, dp[201][201], i, j, la, lb, C = 0;  
        char a[201], b[201], c[402];  
        scanf("%d", &n);  
        while (n--) {  
                scanf("%s%s%s", a, b, c);  
                memset(dp, 0, sizeof(dp));  
                la = strlen(a);  
                lb = strlen(b);  
                for (i = 0; i < la; i++) {  
                        if (a[i] == c[i])  
                                dp[i + 1][0] = 1;  
                        else  
                                break;  
                }  
                for (i = 0; i < lb; i++) {  
                        if (b[i] == c[i])  
                                dp[0][i + 1] = 1;  
                        else  
                                break;  
                }  
                for (i = 1; i <= la; i++)  
                        for (j = 1; j <= lb; j++)  
                                if ((dp[i - 1][j] && a[i - 1] == c[i + j - 1]) || (dp[i][j - 1]  
                                                && b[j - 1] == c[i + j - 1]))  
                                        dp[i][j] = 1;  
                printf("Case %d: ", ++C);  
                puts(dp[la][lb]   "yes" : "no");  
        }  
        return 0;  
}