Neat and clean Recursion + Memoization || Easy to understand
```class Solution {\npublic:\n    string s;\n    int n;\n    int prefix[1001];\n    int len;\n    int dp[1001][1001];\n    int solve(int index, int carpet) {\n 
```class Solution {\npublic:\n    string s;\n    int n;\n    int prefix[1001];\n    int len;\n    int dp[1001][1001];\n    int solve(int index, int carpet) {\n        if(carpet <= 0 || index >= n)\n            return 0;\n        if(dp[index][carpet] != -1)\n            return dp[index][carpet];\n        int x = 0;\n        if(index)\n            x = prefix[index - 1];\n        int y = prefix[min(index + len - 1, n)];\n        return dp[index][carpet] = max(solve(index + 1, carpet), y - x + solve(index + len, carpet - 1));\n    }\n    int minimumWhiteTiles(string floor, int numCarpets, int carpetLen) {\n        s = floor;\n        n = s.length();\n        len = carpetLen;\n        memset(dp, -1, sizeof(dp));\n        prefix[0] = (s[0] == \'1\');\n        for(int i = 1; i < n; ++i)\n            prefix[i] = prefix[i-1] + (s[i] == \'1\');\n        prefix[n] = prefix[n-1];\n        int ans = solve(0, numCarpets);\n        return max(0, prefix[n] - ans);\n    }\n};
['Dynamic Programming', 'Memoization']