Java Bottom Up DP solution O(target * number_of_toppings * number_of_bases)
\npublic class Solution {\n\n    \n    public int closestCost(int[] baseCosts, int[] toppingCosts, int target) {\n        int lb = baseCosts.length;\n        in
```\npublic class Solution {\n\n    \n    public int closestCost(int[] baseCosts, int[] toppingCosts, int target) {\n        int lb = baseCosts.length;\n        int lt = toppingCosts.length;\n\n        ResultHolder resultHolder = new ResultHolder(target);\n\n        int[] toppingCostsExtended = new int[lt*2];\n\t\tint maxToppingCost = 0;\n        //Creating a new array toppingCostsExtended which has 2 elements for each element in toppingCosts\n        // because we can use each topping at most twice\n        for(int i=0;i<lt;i++){\n\t\t\tmaxToppingCost = Math.max(maxToppingCost, toppingCosts[i]);\n            toppingCostsExtended[2*i] = toppingCosts[i];\n            toppingCostsExtended[2*i+1] = toppingCosts[i];\n        }\n\n        for(int k=0;k<lb;k++){\n\n            if(baseCosts[k] == target)\n                return target;\n            if(baseCosts[k] > target){\n                resultHolder.updateBest(baseCosts[k]);\n                continue;\n            }\n\n            findClosestForCurrentBase(toppingCostsExtended,target,maxToppingCost, baseCosts[k], resultHolder );\n            if(resultHolder.diff == 0)\n                return target;\n\n\n        }\n        return resultHolder.curVal;\n    }\n\n    void findClosestForCurrentBase(int[] toppingCostsExtended,int target, int maxToppingCost, int curBaseCost, ResultHolder resultHolder ){\n        int lengthToppingExtended = toppingCostsExtended.length;\n\n        // The closest dessert cost can be (target+maxToppingCost-curBaseCost) in worst case (i.e. largest possible value that can still be our answer)\n        int maxPossibleValue = target + maxToppingCost - curBaseCost;\n\n        //THe DP array tells us if a particular cost can be achieved using toppingCostsExtended\n        boolean[][] dp = new boolean[lengthToppingExtended+1][maxPossibleValue + 1];\n\n        for(int i=0;i<=lengthToppingExtended;i++){\n            dp[i][0] = true;\n        }\n\n        for(int i=1;i<=lengthToppingExtended;i++){\n            for(int j=1; j <= maxPossibleValue; j++){\n                if(dp[i-1][j]){\n                    dp[i][j] =true;\n                }else{\n                    if (j - toppingCostsExtended[i-1] >= 0){\n                        dp[i][j] = dp[i-1][j-toppingCostsExtended[i-1]];\n                    }\n                }\n            }\n        }\n\n        int updatedTarget = target - curBaseCost;\n        //If target can be exactly achieved return that\n        if(dp[lengthToppingExtended][updatedTarget]){\n            resultHolder.updateBest(target);\n\t\t\treturn;\n        }\n\n        //Start from 0 and check what is the best possible dessert cost we can achieve\n        for(int i=0; i<= maxPossibleValue; i++){\n            if(dp[lengthToppingExtended][i]){\n                resultHolder.updateBest(i + curBaseCost);\n            }\n        }\n    }\n\n\n    class ResultHolder{\n        int target;int curVal;int diff;\n\n        ResultHolder(int target){\n            this.target = target;\n            this.curVal = Integer.MIN_VALUE;\n            this.diff = Math.abs(target - curVal);\n        }\n\n        void updateBest(int val){\n            if(Math.abs(target - val) < diff){\n                diff = Math.abs(target - val);\n                curVal = val;\n            }else if(Math.abs(target - val) == diff){\n                if(val < curVal){\n                    curVal = val;\n                }\n            }\n        }\n    }\n}\n```
[]