vacation

 vacationoblem E: Vacation 

The Problem

You are planning to take some rest and to go out on vacation, but you really don't know which cities you should visit. So, you ask your parents for help. Your mother says"My son, you MUST visit Paris, Madrid, Lisboa and London. But it's only fun in this order." Then your father says:"Son, if you're planning to travel, go first to Paris, then to Lisboa, then to London and then, at last, go to Madrid. I know what I'm talking about."

Now you're a bit confused, as you didn't expected this situation. You're afraid that you'll hurt your mother if you follow your father's suggestion. But you're also afraid to hurt your father if you follow you mother's suggestion. But it can get worse, because you can hurt both of them if you simply ignore their suggestions!

Thus, you decide that you'll try to follow their suggestions in the better way that you can. So, you realize that the "Paris-Lisboa-London" order is the one which better satisfies both your mother and your father. Afterwards you can say that you could not visit Madrid, even though you would've liked it very much.

If your father have suggested the "London-Paris-Lisboa-Madrid" order, then you would have two orders, "Paris-Lisboa" and "Paris-Madrid", that would better satisfy both of your parent's suggestions. In this case, you could only visit 2 cities.

You want to avoid problems like this one in the future. And what if their travel suggestions were bigger? Probably you would not find the better way very easy. So, you decided to write a program to help you in this task. You'll represent each city by one character, using uppercase letters, lowercase letters, digits and the space. Thus, you can have at most 63 different cities to visit. But it's possible that you'll visit some city more than once.

If you represent Paris with "a", Madrid with "b", Lisboa with "c" and London with "d", then your mother's suggestion would be "abcd" and you father's suggestion would be "acdb" (or "dacb", in the second example).

The program will read two travel sequences and it must answer how many cities you can travel to such that you'll satisfy both of your parents and it's maximum.

The Input

The input will consist on an arbitrary number of city sequence pairs. The end of input occurs when the first sequence starts with an "#"character (without the quotes). Your program should not process this case. Each travel sequence will be on a line alone and will be formed by legal characters (as defined above). All travel sequences will appear in a single line and will have at most 100 cities.

The Output

For each sequence pair, you must print the following message in a line alone:

Case #d: you can visit at most K cities.
Where d stands for the test case number (starting from 1) and K is the maximum number of cities you can visit such that you'll satisfy both you father's suggestion and you mother's suggestion.

Sample Input

abcd
acdb
abcd
dacb
#

Sample Output

Case #1: you can visit at most 3 cities.
Case #2: you can visit at most 2 cities.

题意是求出给出的每2组字符串的最长公共子序列的长度,坑点是字符串中包括空格,需要用getline、或gets读入。本体运用动态规化dp求解。设有2组序列a={x1,x2,..xn},b={y1,y2,...ym};求他们的最长公共子序列,我们从最后一个元素开始考虑,如果xn=ym,那么lcs=lcs({x1...xn-1},{y1...ym-1})+xn(或ym);如果xn!=ym,则最长公共子序列不能同时包含xn,ym,而是他们中最长的一个lcs=max(lcs({x1,...xn-1},{y1,....ym}),lcs({x1....xn},{y1...ym-1})),由此得以下得递推式:


因为每个i<-X,对应每个j<-Y都存在一个lcs,所以要把每一步的结果放到一个二维数组dp中进行存储,起点设为1,当i=0,或j=0时,此时lcs 一定为0,因此要注意初始化的问题,dp是从1开始的,为了保持一致,序列也是从1开始的,因此要对输入的数据进行预处理。当然也可以都从0开始。

#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#define maxn 110
using namespace std;
int dp[maxn][maxn];
int lcs(string st,string str){
    for(int i=1;i<st.length();i++){
        for(int j=1;j<str.length();j++){
            dp[i][j]=dp[i-1][j];
            if(dp[i][j-1]>dp[i][j]) dp[i][j]=dp[i][j-1];
            if(st[i]==str[j]&&(dp[i-1][j-1]+1)>dp[i][j]){
                dp[i][j]=dp[i-1][j-1]+1;
            }
        }
    }
    return dp[st.length()-1][str.length()-1];
}
int main(){
    string st,str;
    int result=0;
    while(getline(cin,st)){
        if(st=="#") break;
        getline(cin,str);
        string ss=".";
        str=ss+str;
        st=ss+st;
        int num=lcs(st,str);
        result++;
        printf("Case #%d: you can visit at most %d cities.\n",result,num);

    }
    return 0;
}
计算起点从0开始:
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#define maxn 110
using namespace std;
int dp[maxn][maxn];
int lcs(string st,string str){
    for(int i=0;i<st.length();i++){
        for(int j=0;j<str.length();j++){
            if(st[i]==str[j]){
                dp[i+1][j+1]=dp[i][j]+1;
            }
            else dp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);
        }
    }
    return dp[st.length()][str.length()];
}
int main(){
    string st,str;
    int result=0;
    while(getline(cin,st)){
        if(st=="#") break;
        getline(cin,str);
        int num=lcs(st,str);
        result++;
        printf("Case #%d: you can visit at most %d cities.\n",result,num);

    }
    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值