Easy understanding  using recursion +memomization
\nclass Solution {\npublic:\n    int dp1[1002][1002][4];\n    int numTeams(vector<int>& arr) {\n        \n        memset(dp1,-1,sizeof(dp1));\n        \n       
```\nclass Solution {\npublic:\n    int dp1[1002][1002][4];\n    int numTeams(vector<int>& arr) {\n        \n        memset(dp1,-1,sizeof(dp1));\n        \n        \n        int idx=0;\n        int prv=-1;\n        int k=3;\n        int count1=fun1(arr,idx,prv,k);\n        \n        \n        memset(dp1,-1,sizeof(dp1));\n        idx=0;\n        prv=-1;\n        k=3;\n        int count2=fun2(arr,idx,prv,k);\n        \n        return count1+count2;\n    }\n    int fun1(vector<int>&arr,int idx,int prv,int k)\n    {\n        //base\n       \n        if(k==0)\n            return 1;    \n        \n        if(idx>=arr.size() and k>0)\n          return 0;\n        if(idx>=arr.size() and k==0)\n            return 1;\n        \n        if(dp1[idx][prv+1][k]!=-1)\n        {\n            return dp1[idx][prv+1][k];\n        }\n        \n        int choise1=0;\n        int choise2=0;\n        \n        if(prv==-1 or arr[prv]<arr[idx])\n        choise1=fun1(arr,idx+1,idx,k-1);\n        \n        choise2=fun1(arr,idx+1,prv,k);\n        \n        return dp1[idx][prv+1][k] =choise1+choise2;\n    }\n    int fun2(vector<int>&arr,int idx,int prv,int k)\n    {\n        \n        if(k==0)\n            return 1;\n        \n        if(idx>=arr.size() and k>0)\n          return 0;\n        \n        if(idx>=arr.size() and k==0)\n            return 1;\n        \n        if(dp1[idx][prv+1][k]!=-1)\n        {\n            return dp1[idx][prv+1][k];\n        }\n        \n        int choise1=0;\n        int choise2=0;\n        \n        if(prv==-1 or arr[prv]>arr[idx])\n        choise1=fun2(arr,idx+1,idx,k-1);\n        \n        choise2=fun2(arr,idx+1,prv,k);\n        \n        return dp1[idx][prv+1][k] =choise1+choise2;\n    }\n};``\n```
['Dynamic Programming', 'Memoization', 'C', 'C++']