分披萨问题
Problem statement:
问题陈述:
There is a shop which sells pizza of three different sizes- Small, Medium, and Large Pizza. IncludeHelp is crazy for Pizzas. A small Pizza has an area of 'S' unit2, a medium Pizza has an area of 'M' unit2 and a large Pizza has an area of 'L' unit2. Cost of Small, medium and Large Pizza is 'CS' , 'CM', and 'CL' respectively. IncludeHelp wants at least 'X' unit2 of pizza. What is the minimum amount of money needed to buy at least X unit2 of Pizza? If more than one arrangement is possible, choose that one which requires Least Money. Two arrangements are said to be different if They have different quantities of Small, medium, or large pizzas!
有一家商店出售三种不同尺寸的比萨饼-小,中和大比萨饼。 IncludeHelp对于Pizza来说是疯狂的。 小比萨饼的面积为“ S”单元2 ,中比萨饼的面积为“ M”单元2 ,大比萨饼的面积为“ L”单元2 。 小,中,大披萨的价格分别为“ CS” , “ CM”和“ CL” 。 IncludeHelp至少需要比萨饼的“ X”单元2 。 购买至少X比萨饼的第2单元所需的最低金额是多少? 如果可能有不止一种安排,请选择一种需要最少钱的安排。 如果有不同数量的小,中或大比萨饼,则这两种安排据说会有所不同!
Input:
Input contains 6 integers-
X: total area of pizza needed (at least)
S: area of small sized pizza
M: area of medium sized pizza
L: area of large sized pizza
CS: cost of small sized pizza
CM: cost of medium sized pizza
CL: cost of large sized pizza
Output:
Minimum amount of money needed
Constraints
1<=X<=500
1<=S< M< L<=100
1<=CS< CM<CL=1000
Example:
例:
Input:
X : 17
S : 4
M : 6
L : 12
CS: 40
CM: 60
CL: 100
Output:
160
Explanation:
说明:
IncludeHelp wants at least 17 unit2 of Pizza
Few possible arrangements can be,
5 Small pizza (size of 5*4=20) amounting 200
4 small pizza, one medium pizza (size 4*4+6=22) amounting 220
3 small pizza, two medium pizza (size 3*4+2*6=24) amounting 240
...
1 large pizza and 1 medium pizza (size 1*6+1*12=18) amounting 160
And this is the optimal money. No other arrangements can lead to a more optimal solution for this problem( that means we can't minimize the money anymore).
这是最理想的钱。 没有其他安排可以为这个问题找到更理想的解决方案(这意味着我们不能再把金钱减少到最低限度了)。
So, how we can solve the above problem?
那么,如何解决以上问题呢?
To understand the problem, we can figure out that it's quite similar to the knapsack problem with constraints that we have an infinite supply of the pizzas and the number of different kinds of pizzas is three. We need to achieve the total size of pizza while investing the minimum amount of money.
为了理解这个问题,我们可以发现它与背包问题非常相似,但有一个局限性,就是我们有无限量的比萨饼,而不同种类的比萨饼的数量是3。 我们需要在投资最小金额的同时实现比萨的总大小。
So, let,
所以让,
Total area of pizza needed (at least) = X
Area of small sized pizza: S
Area of medium sized pizza: M
Area of large sized pizza: L
Cost of small sized pizza: CS
Cost of medium sized pizza: CM
Cost of large sized pizza: CL
Now,
现在,
f(X) = minimum amount of money to get at least X area of pizza
So, f(X) can be written recursively as,
因此, f(X)可以递归地写为
f(X) = minimum(f(X-S) + CS, f(X-M) + CM, f(X-L) + CL
Where,
哪里,
X-S >= 0, X-m >= 0, X-L >= 0
That means, we choose either of small, medium or large pizza whichever is feasible leading to minimum money for any sub-problem
就是说,我们选择小,中或大披萨,只要可行,就可以使任何子问题的支出降至最低
Since the recursion tree would generate many overlapping subproblems we need to convert it into DP.
由于递归树会生成许多重叠的子问题,因此我们需要将其转换为DP。
Solution Approach:
解决方法:
Converting the recursion into DP:
将递归转换为DP:
1) Declare arr[X+1] and initialize arr[0]=0 which is result for X=0;
2) for i=1 to X //for each size of pizza
// if a small pizza cut is possible then dps=i-S else 0
Set dps=(i-S)≤0?0:(i-S)
// if a medium pizza cut is possible then dpm=i-M else 0
Set dpm=(i-M)<=0?0:(i-M)
// if a large pizza cut is possible then dpm=i-L else 0
Set dpl=(i-L)<=0?0:(i-L)
// find the minimum for this sub-problem
arr[i]=min(arr[dps]+CS,arr[dpm]+CM,arr[dpl]+CL)
end for
3) Return arr[X] which is final result.
C++ Implementation:
C ++实现:
#include <bits/stdc++.h>
using namespace std;
int min(int x, int y, int z)
{
if (x <= y && x <= z)
return x;
if (y <= z)
return y;
return z;
}
void minimumMoney(int X, int S, int M, int L, int CS, int CM, int CL)
{
int arr[X + 1];
arr[0] = 0;
for (int i = 1; i <= X; i++) {
//check for valid pizza part
int dps = (i - S) <= 0 ? 0 : (i - S);
//check for valid pizza part
int dpm = (i - M) <= 0 ? 0 : (i - M);
//check for valid pizza part
int dpl = (i - L) <= 0 ? 0 : (i - L);
//find the minimum
arr[i] = min(arr[dps] + CS, arr[dpm] + CM, arr[dpl] + CL);
}
cout << "Minimum amount of money: " << arr[X] << endl;
}
int main()
{
int X, S, M, L, CS, CM, CL;
cout << "Enter X, total size(at least)\n";
cin >> X;
cout << "Enter S, small pizza size\n";
cin >> S;
cout << "Enter M, medium pizza size\n";
cin >> M;
cout << "Enter L, large pizza size\n";
cin >> L;
cout << "Enter CS,cost of small pizza \n";
cin >> CS;
cout << "Enter CM,cost of medium pizza \n";
cin >> CM;
cout << "Enter CL,cost of large pizza \n";
cin >> CL;
minimumMoney(X, S, M, L, CS, CM, CL);
return 0;
}
Output
输出量
RUN 1:
Enter X, total size(at least)
17
Enter S, small pizza size
4
Enter M, medium pizza size
6
Enter L, large pizza size
12
Enter CS,cost of small pizza
40
Enter CM,cost of medium pizza
60
Enter CL,cost of large pizza
100
Minimum amount of money: 160
RUN 2:
Enter X, total size(at least)
17
Enter S, small pizza size
3
Enter M, medium pizza size
6
Enter L, large pizza size
12
Enter CS,cost of small pizza
50
Enter CM,cost of medium pizza
60
Enter CL,cost of large pizza
100
Minimum amount of money: 160
翻译自: https://www.includehelp.com/icp/pizza-mania-problem.aspx
分披萨问题