给定长度为L的杆,任务是将杆切割,以使长度p,q和r的段总数最大。这些段的长度只能是p,q和r。
例子:
Input: l = 11, p = 2, q = 3, r = 5
Output: 5
Segments of 2, 2, 2, 2 and 3
Input: l = 7, p = 2, q = 5, r = 5
Output: 2
Segments of 2 and 5
方法:
由于在给定长度上可以切割的最大数量的解决方案取决于先前在较短长度上切割的最大数量,因此可以通过动态编程的方法解决此问题。假设我们给定长度’l’ 。为了找到可以在长度’l’中进行切割的最大数量,请分别查找在较短的先前长度’lp’,’lq’,’lr’中进行切割的数量。所需的答案将是max(lp,lq,lr)+1,因为在此之后需要再切割一次以切割长度’l’ 。因此,对于给定的长度要解决此问题,请找到可在‘1’到’l’长度范围内进行切割的最大数量。
例子:
l = 11, p = 2, q = 3, r = 5
Analysing lengths from 1 to 11:
- Not possible to cut->0
- Possible cut is of lengths 2->1 (2)
- Possible cut is of lengths 3->1 (3)
- Possible cuts are of lengths max(arr[4-2],arr[4-3])+1->2 (2,2)
- Possible cuts are of lengths max(arr[5-2],arr[5-3])+1->2 (2,3)
- Possible cuts are of lengths max(arr[6-2],arr[6-3],arr[6-5])+1->3 (2,2,2)
- Possible cuts are of lengths max(arr[7-2],arr[7-3],arr[7-5])+1->3 (2,3,2) or (2,2,3)
- Possible cuts are of lengths max(arr[8-2],arr[8-3],arr[8-5])+1->4 (2,2,2,2)
- Possible cuts are of lengths max(arr[9-2],arr[9-3],arr[9-5])+1->4 (2,3,2,2) or (2,2,3,2) or (2,2,2,3)
- Possible cuts are of lengths max(arr[10-2],arr[10-3],arr[10-5])+1->5 (2,2,2,2,2)
- Possible cuts are of lengths max(arr[11-2],arr[11-3],arr[11-5])+1->5 (2,3,2,2,2) or (2,2,3,2,2) or (2,2,2,3,2) or (2,2,2,2,3)
算法:
- 初始化数组DP [] = {-1}和DP [0] = 0 。
- 从“ 1”到“ l”运行循环
- 如果DP [i] =-1表示不可能使用给定段p,q,r对其进行划分,请继续;
- DP [i + p] = max(DP [i + p],DP [i] +1)
- DP [i + q] = max(DP [i + q],DP [i] +1)
- DP [i + r] = max(DP [i + r],DP [i] +1)
- 打印DP [l]
伪代码:
DP[l+1]={-1}
DP[0]=0
for(i from 0 to l)
if(DP[i]==-1)
continue
DP[i+p]=max(DP[i+p],DP[i]+1)
DP[i+q]=max(DP[i+q],DP[i]+1)
DP[i+r]=max(DP[i+r],DP[i]+1)
print(DP[l])
执行:
C++
// C++ program to maximize the number
// of segments of length p, q and r
#include
using namespace std;
// Function that returns the maximum number
// of segments possible
int findMaximum(int l, int p, int q, int r)
{
// Array to store the cut at each length
int dp[l + 1];
// All values with -1
memset(dp, -1, sizeof(dp));
// if length of rod is 0 then total cuts will be 0
// so, initialize the dp[0] with 0
dp[0] = 0;
for (int i = 0; i <= l; i++) {
// if certain length is not possible
if (dp[i] == -1)
continue;
// if a segment of p is possible
if (i + p <= l)
dp[i + p] = max(dp[i + p], dp[i] + 1);
// if a segment of q is possible
if (i + q <= l)
dp[i + q] = max(dp[i + q], dp[i] + 1);
// if a segment of r is possible
if (i + r <= l)
dp[i + r] = max(dp[i + r], dp[i] + 1);
}
// if no segment can be cut then return 0
if (dp[l] == -1) {
dp[l] = 0;
}
// return value corresponding to length l
return dp[l];
}
// Driver Code
int main()
{
int l = 11, p = 2, q = 3, r = 5;
// Calling Function
int ans = findMaximum(l, p, q, r);
cout << ans;
return 0;
}
Java
// Java program to maximize
// the number of segments
// of length p, q and r
import java.io.*;
class GFG {
// Function that returns
// the maximum number
// of segments possible
static int findMaximum(int l, int p, int q, int r)
{
// Array to store the
// cut at each length
int dp[] = new int[l + 1];
// All values with -1
for (int i = 0; i < l + 1; i++)
dp[i] = -1;
// if length of rod is 0
// then total cuts will
// be 0 so, initialize
// the dp[0] with 0
dp[0] = 0;
for (int i = 0; i <= l; i++) {
// if certain length
// is not possible
if (dp[i] == -1)
continue;
// if a segment of
// p is possible
if (i + p <= l)
dp[i + p] = Math.max(dp[i + p], dp[i] + 1);
// if a segment of
// q is possible
if (i + q <= l)
dp[i + q] = Math.max(dp[i + q], dp[i] + 1);
// if a segment of
// r is possible
if (i + r <= l)
dp[i + r] = Math.max(dp[i + r], dp[i] + 1);
}
// if no segment can be cut then return 0
if (dp[l] == -1) {
dp[l] = 0;
}
// return value corresponding
// to length l
return dp[l];
}
// Driver Code
public static void main(String[] args)
{
int l = 11, p = 2, q = 3, r = 5;
// Calling Function
int ans = findMaximum(l, p, q, r);
System.out.println(ans);
}
}
// This code is contributed
// by anuj_67.
Python 3
# Python 3 program to
# maximize the number
# of segments of length
# p, q and r
# Function that returns
# the maximum number
# of segments possible
def findMaximum(l, p, q, r):
# Array to store the cut
# at each length
# All values with -1
dp = [-1]*(l + 1)
# if length of rod is 0 then
# total cuts will be 0
# so, initialize the dp[0] with 0
dp[0] = 0
for i in range(l+1):
# if certain length is not
# possible
if (dp[i] == -1):
continue
# if a segment of p is possible
if (i + p <= l):
dp[i + p] = (max(dp[i + p],
dp[i] + 1))
# if a segment of q is possible
if (i + q <= l):
dp[i + q] = (max(dp[i + q],
dp[i] + 1))
# if a segment of r is possible
if (i + r <= l):
dp[i + r] = (max(dp[i + r],
dp[i] + 1))
# if no segment can be cut then return 0
if dp[l] == -1:
dp[l] = 0
# return value corresponding
# to length l
return dp[l]
# Driver Code
if __name__ == "__main__":
l = 11
p = 2
q = 3
r = 5
# Calling Function
ans = findMaximum(l, p, q, r)
print(ans)
# This code is contributed by
# ChitraNayal
C#
// C# program to maximize
// the number of segments
// of length p, q and r
using System;
class GFG {
// Function that returns
// the maximum number
// of segments possible
static int findMaximum(int l, int p,
int q, int r)
{
// Array to store the
// cut at each length
int[] dp = new int[l + 1];
// All values with -1
for (int i = 0; i < l + 1; i++)
dp[i] = -1;
// if length of rod is 0
// then total cuts will
// be 0 so, initialize
// the dp[0] with 0
dp[0] = 0;
for (int i = 0; i <= l; i++) {
// if certain length
// is not possible
if (dp[i] == -1)
continue;
// if a segment of
// p is possible
if (i + p <= l)
dp[i + p] = Math.Max(dp[i + p],
dp[i] + 1);
// if a segment of
// q is possible
if (i + q <= l)
dp[i + q] = Math.Max(dp[i + q],
dp[i] + 1);
// if a segment of
// r is possible
if (i + r <= l)
dp[i + r] = Math.Max(dp[i + r],
dp[i] + 1);
}
// if no segment can be cut then return 0
if (dp[l] == -1) {
dp[l] = 0;
}
// return value corresponding
// to length l
return dp[l];
}
// Driver Code
public static void Main()
{
int l = 11, p = 2, q = 3, r = 5;
// Calling Function
int ans = findMaximum(l, p, q, r);
Console.WriteLine(ans);
}
}
// This code is contributed
// by anuj_67.
Javascript
5
复杂度分析:
- 时间复杂度: O(N)。
使用单个for循环直到长度’N’。 - 辅助空间: O(N)。
使用数组“ DP”来跟踪分段
注意:此问题也可以被视为最小硬币找零问题,因为我们有一定的获取长度,该长度与需要最小找零的金额相等。现在,x,y,z与给定硬币的面额相同。因此,长度等于数量,xyz等于面额,因此我们只需要更改一个条件,而不是找到最小值,我们需要找到最大值,我们将得到答案。因为最小硬币找零问题是基本的动态问题。编程问题,因此这也将有助于解决该问题。
在最小硬币找零问题中我们需要改变的条件
for(ll i=1;i<=n;i++)
{
for(ll j=1;j<=3;j++)
{
if(i>=a[j]&&m[i-a[j]]!=-1)
{
dp[i]=max(dp[i],1+dp[i-a[j]]);
}
}
}
如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。