<p>Given a string&nbsp;<code>s</code><var>,</var>&nbsp;return <em>the maximum&nbsp;number of unique substrings that the given string can be split into</em>.</p>

<p>You can split string&nbsp;<code>s</code> into any list of&nbsp;<strong>non-empty substrings</strong>, where the concatenation of the substrings forms the original string.&nbsp;However, you must split the substrings such that all of them are <strong>unique</strong>.</p>

<p>A <strong>substring</strong> is a contiguous sequence of characters within a string.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> s = &quot;ababccc&quot;
<strong>Output:</strong> 5
<strong>Explanation</strong>: One way to split maximally is [&#39;a&#39;, &#39;b&#39;, &#39;ab&#39;, &#39;c&#39;, &#39;cc&#39;]. Splitting like [&#39;a&#39;, &#39;b&#39;, &#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;cc&#39;] is not valid as you have &#39;a&#39; and &#39;b&#39; multiple times.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> s = &quot;aba&quot;
<strong>Output:</strong> 2
<strong>Explanation</strong>: One way to split maximally is [&#39;a&#39;, &#39;ba&#39;].
</pre>

<p><strong class="example">Example 3:</strong></p>

<pre>
<strong>Input:</strong> s = &quot;aa&quot;
<strong>Output:</strong> 1
<strong>Explanation</strong>: It is impossible to split the string any further.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li>
	<p><code>1 &lt;= s.length&nbsp;&lt;= 16</code></p>
	</li>
	<li>
	<p><code>s</code> contains&nbsp;only lower case English letters.</p>
	</li>
</ul>

class Solution {
private:
    string s;
    int n, ans;
    void f(int i,string lfs,unordered_set<string>& sss){
        if(i==n){
            if(sss.find(lfs)!=sss.end())
                return;
            ans = max(ans,(int)(size(sss))+1);
            return;
        }
        if(sss.find(lfs)==sss.end()){
            sss.insert(lfs);
            string x;
            x.push_back(s[i]);
            f(i+1,x,sss);
            sss.erase(lfs);
        }
        lfs.push_back(char(s[i]));
        f(i+1,lfs,sss);
    }
public:
    int maxUniqueSplit(string s) {
        this->s = s;
        this->n = size(s);
        this->ans = 0;
        // for every char moving forward we have option 
        // option 1 : add this char in last string that is being formatted
        // option 2 : dont add this in the last formatted string and if
        // possible start a new string from here
        // string last_formatted_string = to_string(s[0]);
        unordered_set<string> sss;
        string lfs;
        lfs.push_back(s[0]);
        f(1,lfs,sss);
        return ans;
    }
};
38549