给出两个正整数x,y,另给出若干个数对[ai,bi,ci],请挑选若干数对使得挑出的数对ai的和不小于x,bi的和不小于y,计算挑出数对的ci的和的最小值
注:
每个数对只能挑选一次,x和y均小于2000
5,60,[[3,36,120],[10,25,129],[5,50,250],[1,45,130],[4,20,119]]
249
挑选第一和第二个数对
每种大包装只能最多买一个,所需面包breadNum、饮料的总量beverageNum均不超过2000牛妹一定能找到满足要求的方案让大家能够出游。
class Solution { public: int min = 99999; int mybreadNum = 0; int mybeverageNum = 0; int size; int minCost(int breadNum, int beverageNum, vector<vector<int> >& packageSum) { // write code here mybreadNum = breadNum; mybeverageNum = beverageNum; size = packageSum.size(); DFS(0,0,0,0,packageSum); return min; } void DFS(int index,int currentx,int currenty,int currentt,vector<vector<int> >& mypackageSum) { if(index==size) { return; } if(mypackageSum[index][0] + currentx > mybreadNum) { if(mypackageSum[index][1] + currenty > mybeverageNum) { if(mypackageSum[index][2] + currentt < min) { min = mypackageSum[index][2] + currentt; } } } DFS(index+1,currentx,currenty,currentt,mypackageSum); if(currentt + mypackageSum[index][2] < min) { DFS(index+1,currentx+mypackageSum[index][0],mypackageSum[index][1] + currenty, mypackageSum[index][2] + currentt,mypackageSum); } } };
class Solution { public: int size; int minCost(int breadNum, int beverageNum, vector<vector<int> >& packageSum) { // write code here size = packageSum.size(); //行数(可选的捆绑产品数) int dp[breadNum+1][beverageNum+1]; //dp[i][j]:当需要i个面包和j个饮料时花费的最少钱 for(int i=0;i<=breadNum;i++) { for(int j=0;j<=beverageNum;j++) { dp[i][j] = 99999; } } dp[0][0] = 0; for(int k=0;k<size;k++) //第一层循环,遍历所有货品 { for(int i=breadNum;i>=0;i--) //第二层循环,枚举需要的面包数 { //倒序原因:滚动数组策略,省略了上一个货品时的空间,即当前dp[i][j]实际保存的是上一个货品dp的状态 for(int j=beverageNum;j>=0;j--) //二维背包问题,三维数组滚动优化为二维数组 { dp[i][j] = min(dp[i][j], dp[max(i-packageSum[k][0],0)][max(j-packageSum[k][1],0)] +packageSum[k][2]); } } } return dp[breadNum][beverageNum]; };