kavishrox's blog

By kavishrox, 10 years ago, In English

Hi,

I was trying to code a problem on printing all possible LIS of a string in sorted order. The link to the problem is http://www.spoj.com/problems/UPSUB/. My idea is simply to calculate a 2D LCS matrix by LCS(string s, sort(string s)) and then backtrack over the LCS matrix with optimization to get all the LIS. I am facing problems in optimizing my backtracking code because its visiting way too many states that required.

#include <bits/stdc++.h>
using namespace std;
/*u,l,d correspond to the possible directions from which the maximum value of the LCS array came from*/
struct node{
    int val,u,l,d;
};
int n,maxlen;
set<string> ans;
string s,s1;
//int vis[110][110];
vector<vector<node > > dp;
/*calculates LIS=LCS(s,sort(s))*/
void lis(void){
    s1=s;
    sort(s1.begin(),s1.end());
    //cout<<s1<<endl;
    for(int i=1;i<=n;i++){
        for(int j=0;j<=n;j++){
            if(s1[i-1]==s[j-1]){
                /*if(i==1 and j==2)
                    cout<<"Came wrong way "<<endl;*/
                int x=max(max(dp[i-1][j].val,dp[i][j-1].val),dp[i-1][j-1].val+1);
                dp[i][j].val=x;
                if(dp[i-1][j].val==x){
                    dp[i][j].u=1;
                }
                if(dp[i][j-1].val==x){
                    dp[i][j].l=1;
                }
                if((dp[i-1][j-1].val+1)==x){
                    dp[i][j].d=1;
                }
            }
            else{
                int x=max(dp[i-1][j].val,dp[i][j-1].val);
                dp[i][j].val=x;
                if(dp[i-1][j].val==x){
                    dp[i][j].u=1;
                }
                if(dp[i][j-1].val==x){
                    dp[i][j].l=1;
                }
            }
        }
    }
    maxlen=dp[n][n].val;
    //cout<<maxlen<<endl;
}
string st;
void dfs(int x,int y){
    cout<<"now at "<<x<<"\t"<<y<<endl;
    if(x==0 or y==0){
        if(st.size()==maxlen){
            set<string>::iterator it=ans.begin();
            ans.insert(it,st);
            //cout<<"print at "<<x<<"\t"<<y<<endl;
        }
        return;
    }
    if(dp[x][y].d==1 ){
        st=s[y-1]+st;
        dfs(x-1,y-1);
        st.erase(st.begin(),st.begin()+1);
    }
    if(dp[x][y].u==1){
        dfs(x-1,y);
    }
    if(dp[x][y].l==1){
        dfs(x,y-1);
    }
}
void print_lis(void){
    for(int i=0;i<=n;i++){
        cout<<endl;
        for(int j=0;j<=n;j++){
            cout<<dp[i][j].val<<"\t";
        }
    }
    cout<<endl;
}
int main(void){
    int tc;
    cin>>tc;
    while(tc--){
        cin>>s;
        n=s.size();
        dp.resize(n+1);
        for(int i=0;i<=n;i++){
            dp[i].resize(n+1);
        }
        lis();
        //print_lis();
        dfs(n,n);
        //sort(ans.begin(),ans.end());
        for(set<string>::iterator it=ans.begin();it!=ans.end();it++)
            cout<<*it<<endl;
    }
    return 0;
}

Please suggest me some ways by which I can optimize the dfs(i,j) part.

  • Vote: I like it
  • -3
  • Vote: I do not like it

»
10 years ago, # |
  Vote: I like it 0 Vote: I do not like it

use caching in dfs function ;)