POJ 1458题解

来源:互联网 发布:星星知多少钻石大陆 编辑:程序博客网 时间:2024/05/22 00:35

这是一道更为典型的LCS题目,不同与以往的解法,我们不用DP来做,直接用转换为LIS的思路来做。

题目:

http://poj.org/problem?id=1458

代码:

#include <cstdlib>#include <cstdio>#include<iostream>#include<vector>using namespace std;//二分法求最长单调递增子序列关键字下标(<)int binarySearch4(int key,int lowIndex,int highIndex,vector<int>&v2){    if(lowIndex==highIndex)    {       if(v2[lowIndex] == key)        {            return lowIndex;        }        else if(lowIndex == 0 && key<v2[0])        {            return lowIndex;        }        return lowIndex+1;    }    int midIndex = (lowIndex + highIndex + 1)/2;    if(key<v2[midIndex])    {        return binarySearch4(key,lowIndex,midIndex-1,v2);    }    else    {        return binarySearch4(key,midIndex,highIndex,v2);    }}int countTotal(vector<int>&v1){    int lowIndex = 0;    vector<int> v2;    v2.push_back(v1[0]);        for(int i=1;i<v1.size();i++)    {        lowIndex = binarySearch4(v1[i],0,v2.size()-1,v2);        if(lowIndex>v2.size()-1)        {            v2.push_back(v1[i]);        }        else        {            v2[lowIndex] = v1[i];        }    }    if(v2[v2.size()-1]==0)    {        return v2.size()-1;    }    else    {        return v2.size();    }}int main(){    string str1;    string str2;    while(cin>>str1>>str2)    {        vector<int> v1;      //将第一个序列的元素在第二个序列的出现位置从大到小,从左到右排列起来       for(int i=0;i<str1.length();i++)        {            for(int j=str2.length()-1;j>=0;j--)            {                if(str1[i] == str2[j])                {                    v1.push_back(j+1);                }            }        }        if(v1.size()==0)        {            cout<<"0"<<endl;        }        else        {            cout<<countTotal(v1)<<endl;        }        /*for(int i=0;i<v1.size();i++)        {            cout<<v1[i];        }        cout<<endl;*/    }}

用求LIS的方法来求LCS的方法对应的还有一道题目:

POJ1159题:

http://poj.org/problem?id=1159

但是需要N平方的空间复杂度,因而这题A不掉,提示Memory Limit Exceeded。。。单思路应该是没错的。

对应代码:

#include <iostream>#include <cstdlib>#include <cstdio>#include <vector>using namespace std;int n;string str;vector<int> v1;vector<int> v2;//二分法求最长单调递增子序列关键字下标(<)int binarySearch4(int key,int lowIndex,int highIndex){    if (lowIndex==highIndex)    {        if (v2[lowIndex] == key)        {            return lowIndex;        }        else if (lowIndex == 0 && key<v2[0])        {            return lowIndex;        }        return lowIndex+1;    }    int midIndex = (lowIndex + highIndex + 1)/2;    if (key<v2[midIndex])    {        return binarySearch4(key,lowIndex,midIndex-1);    }    else    {        return binarySearch4(key,midIndex,highIndex);    }}int countTotal(){    int lowIndex = 0;    v2.push_back(v1[0]);    //将第一个序列的元素在第二个序列的出现位置从大到小,从左到右排列起来    for (int i=1;i<v1.size();i++)    {        lowIndex = binarySearch4(v1[i],0,v2.size()-1);        if (lowIndex>v2.size()-1)        {            v2.push_back(v1[i]);        }        else        {            v2[lowIndex] = v1[i];        }    }    if (v2[v2.size()-1]==0)    {        return v2.size()-1;    }    else    {        return v2.size();    }}int main(){   cin>>n>>str;    for (int i=0;i<str.length();i++)    {        for (int j=0;j<str.length();j++)        {            if (str[i] == str[j])            {                v1.push_back(str.length()-j);            }        }    }    if (v1.size()==0)    {        cout<<"0"<<endl;    }    else    {        cout<<n-countTotal()<<endl;    }    /*for (int i=0;i<v1.size();i++)    {        cout<<v1[i];    }    cout<<endl;*/    return 0;}


原创粉丝点击