Nice solution.

for(int j = D.size() - 1; j >= 0; j--){
if(D[j].back() + 1 == nums[i]){
D[j].push_back(nums[i]);
inserted = true;
break;
}
}

The sequence from the back of vector<vector<int> > D has the priority to insert nums[i]. However, we can first check the sequences on the front side of D to remove the redundant sequence seq whose element on the back seq.back() is smaller than nums[i]-1. It is no longer available since the numbers in nums are sorted ascending and no other elements after nums[i] can be inserted into seq. Before we remove it, if we find out that seq.size()<3, we can say that the problem is impossible and stop at half.

For example, nums = [1,2,3,5,6,8,9,10, ...]. When reaching element 8, D looks like this:D = [[1,2,3],[5,6]]. Instead of inserting a new sequence to the back D = [[1,2,3],[5,6],[8]], we can first remove the front sequence [1,2,3], because elements after 8 can't be inserted into it. Then, we find out next sequence [5,6] size is smaller than 3. We can return false at half. We don't need to look up all the elements in nums. It can run faster.

I modified your code as follow:

bool isPossible(vector<int>& nums) {
deque<vector<int>> D;
if(nums.empty()){
return false;
}
for(int i=0; i<nums.size(); ++i){
bool inserted = false;
//check the sequences on the front side of D
while(!D.empty() && D.front().back()<nums[i]-1){
if(D.front().size()<3)
return false;
D.pop_front();
}
for(int j=D.size()-1; j>=0; j--){
if(D[j].back()+1 == nums[i]){
D[j].push_back(nums[i]);
inserted = true;
break;
}
}
if(!inserted)
D.push_back(vector<int>(1,nums[i]));
}
for(int i=D.size()-1; i>=0; i--)
if(D[i].size() < 3)
return false;
return true;
}