Java - Recursion + Memoization Solution
java []\nclass Solution {\n    private List<List<Integer>> arr;\n    private Integer dp[][];\n\n    public int maxScore(List<List<Integer>> grid) {\n        arr
```java []\nclass Solution {\n    private List<List<Integer>> arr;\n    private Integer dp[][];\n\n    public int maxScore(List<List<Integer>> grid) {\n        arr = new ArrayList<>();\n        dp = new Integer[101][1 << grid.size()];\n\n        for (int i = 0; i <= 100; i++) {\n            arr.add(new ArrayList<Integer>());\n        }\n        \n        // For every value in grid, store the row numbers\n        for (int i = 0; i < grid.size(); i++) {\n            for (int num: grid.get(i)) {\n                arr.get(num).add(i);\n            }\n        }\n\n        // search from 100 -> 1 and get the sum\n        return getScore(100, 0);\n    }\n\n    private int getScore(int curItem, int mask) {\n        if (curItem <= 0) {\n            return 0;\n        }\n\n        if (dp[curItem][mask] != null) {\n            return dp[curItem][mask];\n        }\n\n        // search for value less than current, with same set of rows\n        int score = getScore(curItem - 1, mask);\n\n        // get rows where current value is present, and\n        // try them 1 by 1\n        for (int row : arr.get(curItem)) {\n            if ((mask & (1 << row)) > 0) {\n                continue;\n            }\n\n            score = Math.max(score, curItem + getScore(curItem - 1, mask | (1 << row)));\n        }\n\n        return dp[curItem][mask] = score;\n    }\n}\n```
['Dynamic Programming', 'Recursion', 'Memoization', 'Bitmask', 'Java']