This commit is contained in:
krahets
2024-05-06 05:27:10 +08:00
parent 2395804410
commit 7e7eb6047a
56 changed files with 3908 additions and 42257 deletions

View File

@@ -43,29 +43,29 @@ We have created an `Item` class in order to sort the items by their unit value.
```python title="fractional_knapsack.py"
class Item:
"""物品"""
"""Item"""
def __init__(self, w: int, v: int):
self.w = w # 物品重量
self.v = v # 物品价值
self.w = w # Item weight
self.v = v # Item value
def fractional_knapsack(wgt: list[int], val: list[int], cap: int) -> int:
"""分数背包:贪心"""
# 创建物品列表,包含两个属性:重量、价值
"""Fractional knapsack: Greedy"""
# Create an item list, containing two properties: weight, value
items = [Item(w, v) for w, v in zip(wgt, val)]
# 按照单位价值 item.v / item.w 从高到低进行排序
# Sort by unit value item.v / item.w from high to low
items.sort(key=lambda item: item.v / item.w, reverse=True)
# 循环贪心选择
# Loop for greedy selection
res = 0
for item in items:
if item.w <= cap:
# 若剩余容量充足,则将当前物品整个装进背包
# If the remaining capacity is sufficient, put the entire item into the knapsack
res += item.v
cap -= item.w
else:
# 若剩余容量不足,则将当前物品的一部分装进背包
# If the remaining capacity is insufficient, put part of the item into the knapsack
res += (item.v / item.w) * cap
# 已无剩余容量,因此跳出循环
# No remaining capacity left, thus break the loop
break
return res
```
@@ -73,50 +73,18 @@ We have created an `Item` class in order to sort the items by their unit value.
=== "C++"
```cpp title="fractional_knapsack.cpp"
/* 物品 */
class Item {
public:
int w; // 物品重量
int v; // 物品价值
[class]{Item}-[func]{}
Item(int w, int v) : w(w), v(v) {
}
};
/* 分数背包:贪心 */
double fractionalKnapsack(vector<int> &wgt, vector<int> &val, int cap) {
// 创建物品列表,包含两个属性:重量、价值
vector<Item> items;
for (int i = 0; i < wgt.size(); i++) {
items.push_back(Item(wgt[i], val[i]));
}
// 按照单位价值 item.v / item.w 从高到低进行排序
sort(items.begin(), items.end(), [](Item &a, Item &b) { return (double)a.v / a.w > (double)b.v / b.w; });
// 循环贪心选择
double res = 0;
for (auto &item : items) {
if (item.w <= cap) {
// 若剩余容量充足,则将当前物品整个装进背包
res += item.v;
cap -= item.w;
} else {
// 若剩余容量不足,则将当前物品的一部分装进背包
res += (double)item.v / item.w * cap;
// 已无剩余容量,因此跳出循环
break;
}
}
return res;
}
[class]{}-[func]{fractionalKnapsack}
```
=== "Java"
```java title="fractional_knapsack.java"
/* 物品 */
/* Item */
class Item {
int w; // 物品重量
int v; // 物品价值
int w; // Item weight
int v; // Item value
public Item(int w, int v) {
this.w = w;
@@ -124,26 +92,26 @@ We have created an `Item` class in order to sort the items by their unit value.
}
}
/* 分数背包:贪心 */
/* Fractional knapsack: Greedy */
double fractionalKnapsack(int[] wgt, int[] val, int cap) {
// 创建物品列表,包含两个属性:重量、价值
// Create an item list, containing two properties: weight, value
Item[] items = new Item[wgt.length];
for (int i = 0; i < wgt.length; i++) {
items[i] = new Item(wgt[i], val[i]);
}
// 按照单位价值 item.v / item.w 从高到低进行排序
// Sort by unit value item.v / item.w from high to low
Arrays.sort(items, Comparator.comparingDouble(item -> -((double) item.v / item.w)));
// 循环贪心选择
// Loop for greedy selection
double res = 0;
for (Item item : items) {
if (item.w <= cap) {
// 若剩余容量充足,则将当前物品整个装进背包
// If the remaining capacity is sufficient, put the entire item into the knapsack
res += item.v;
cap -= item.w;
} else {
// 若剩余容量不足,则将当前物品的一部分装进背包
// If the remaining capacity is insufficient, put part of the item into the knapsack
res += (double) item.v / item.w * cap;
// 已无剩余容量,因此跳出循环
// No remaining capacity left, thus break the loop
break;
}
}
@@ -154,343 +122,73 @@ We have created an `Item` class in order to sort the items by their unit value.
=== "C#"
```csharp title="fractional_knapsack.cs"
/* 物品 */
class Item(int w, int v) {
public int w = w; // 物品重量
public int v = v; // 物品价值
}
[class]{Item}-[func]{}
/* 分数背包:贪心 */
double FractionalKnapsack(int[] wgt, int[] val, int cap) {
// 创建物品列表,包含两个属性:重量、价值
Item[] items = new Item[wgt.Length];
for (int i = 0; i < wgt.Length; i++) {
items[i] = new Item(wgt[i], val[i]);
}
// 按照单位价值 item.v / item.w 从高到低进行排序
Array.Sort(items, (x, y) => (y.v / y.w).CompareTo(x.v / x.w));
// 循环贪心选择
double res = 0;
foreach (Item item in items) {
if (item.w <= cap) {
// 若剩余容量充足,则将当前物品整个装进背包
res += item.v;
cap -= item.w;
} else {
// 若剩余容量不足,则将当前物品的一部分装进背包
res += (double)item.v / item.w * cap;
// 已无剩余容量,因此跳出循环
break;
}
}
return res;
}
[class]{fractional_knapsack}-[func]{FractionalKnapsack}
```
=== "Go"
```go title="fractional_knapsack.go"
/* 物品 */
type Item struct {
w int // 物品重量
v int // 物品价值
}
[class]{Item}-[func]{}
/* 分数背包:贪心 */
func fractionalKnapsack(wgt []int, val []int, cap int) float64 {
// 创建物品列表,包含两个属性:重量、价值
items := make([]Item, len(wgt))
for i := 0; i < len(wgt); i++ {
items[i] = Item{wgt[i], val[i]}
}
// 按照单位价值 item.v / item.w 从高到低进行排序
sort.Slice(items, func(i, j int) bool {
return float64(items[i].v)/float64(items[i].w) > float64(items[j].v)/float64(items[j].w)
})
// 循环贪心选择
res := 0.0
for _, item := range items {
if item.w <= cap {
// 若剩余容量充足,则将当前物品整个装进背包
res += float64(item.v)
cap -= item.w
} else {
// 若剩余容量不足,则将当前物品的一部分装进背包
res += float64(item.v) / float64(item.w) * float64(cap)
// 已无剩余容量,因此跳出循环
break
}
}
return res
}
[class]{}-[func]{fractionalKnapsack}
```
=== "Swift"
```swift title="fractional_knapsack.swift"
/* 物品 */
class Item {
var w: Int // 物品重量
var v: Int // 物品价值
[class]{Item}-[func]{}
init(w: Int, v: Int) {
self.w = w
self.v = v
}
}
/* 分数背包:贪心 */
func fractionalKnapsack(wgt: [Int], val: [Int], cap: Int) -> Double {
// 创建物品列表,包含两个属性:重量、价值
var items = zip(wgt, val).map { Item(w: $0, v: $1) }
// 按照单位价值 item.v / item.w 从高到低进行排序
items.sort { -(Double($0.v) / Double($0.w)) < -(Double($1.v) / Double($1.w)) }
// 循环贪心选择
var res = 0.0
var cap = cap
for item in items {
if item.w <= cap {
// 若剩余容量充足,则将当前物品整个装进背包
res += Double(item.v)
cap -= item.w
} else {
// 若剩余容量不足,则将当前物品的一部分装进背包
res += Double(item.v) / Double(item.w) * Double(cap)
// 已无剩余容量,因此跳出循环
break
}
}
return res
}
[class]{}-[func]{fractionalKnapsack}
```
=== "JS"
```javascript title="fractional_knapsack.js"
/* 物品 */
class Item {
constructor(w, v) {
this.w = w; // 物品重量
this.v = v; // 物品价值
}
}
[class]{Item}-[func]{}
/* 分数背包:贪心 */
function fractionalKnapsack(wgt, val, cap) {
// 创建物品列表,包含两个属性:重量、价值
const items = wgt.map((w, i) => new Item(w, val[i]));
// 按照单位价值 item.v / item.w 从高到低进行排序
items.sort((a, b) => b.v / b.w - a.v / a.w);
// 循环贪心选择
let res = 0;
for (const item of items) {
if (item.w <= cap) {
// 若剩余容量充足,则将当前物品整个装进背包
res += item.v;
cap -= item.w;
} else {
// 若剩余容量不足,则将当前物品的一部分装进背包
res += (item.v / item.w) * cap;
// 已无剩余容量,因此跳出循环
break;
}
}
return res;
}
[class]{}-[func]{fractionalKnapsack}
```
=== "TS"
```typescript title="fractional_knapsack.ts"
/* 物品 */
class Item {
w: number; // 物品重量
v: number; // 物品价值
[class]{Item}-[func]{}
constructor(w: number, v: number) {
this.w = w;
this.v = v;
}
}
/* 分数背包:贪心 */
function fractionalKnapsack(wgt: number[], val: number[], cap: number): number {
// 创建物品列表,包含两个属性:重量、价值
const items: Item[] = wgt.map((w, i) => new Item(w, val[i]));
// 按照单位价值 item.v / item.w 从高到低进行排序
items.sort((a, b) => b.v / b.w - a.v / a.w);
// 循环贪心选择
let res = 0;
for (const item of items) {
if (item.w <= cap) {
// 若剩余容量充足,则将当前物品整个装进背包
res += item.v;
cap -= item.w;
} else {
// 若剩余容量不足,则将当前物品的一部分装进背包
res += (item.v / item.w) * cap;
// 已无剩余容量,因此跳出循环
break;
}
}
return res;
}
[class]{}-[func]{fractionalKnapsack}
```
=== "Dart"
```dart title="fractional_knapsack.dart"
/* 物品 */
class Item {
int w; // 物品重量
int v; // 物品价值
[class]{Item}-[func]{}
Item(this.w, this.v);
}
/* 分数背包:贪心 */
double fractionalKnapsack(List<int> wgt, List<int> val, int cap) {
// 创建物品列表,包含两个属性:重量、价值
List<Item> items = List.generate(wgt.length, (i) => Item(wgt[i], val[i]));
// 按照单位价值 item.v / item.w 从高到低进行排序
items.sort((a, b) => (b.v / b.w).compareTo(a.v / a.w));
// 循环贪心选择
double res = 0;
for (Item item in items) {
if (item.w <= cap) {
// 若剩余容量充足,则将当前物品整个装进背包
res += item.v;
cap -= item.w;
} else {
// 若剩余容量不足,则将当前物品的一部分装进背包
res += item.v / item.w * cap;
// 已无剩余容量,因此跳出循环
break;
}
}
return res;
}
[class]{}-[func]{fractionalKnapsack}
```
=== "Rust"
```rust title="fractional_knapsack.rs"
/* 物品 */
struct Item {
w: i32, // 物品重量
v: i32, // 物品价值
}
[class]{Item}-[func]{}
impl Item {
fn new(w: i32, v: i32) -> Self {
Self { w, v }
}
}
/* 分数背包:贪心 */
fn fractional_knapsack(wgt: &[i32], val: &[i32], mut cap: i32) -> f64 {
// 创建物品列表,包含两个属性:重量、价值
let mut items = wgt
.iter()
.zip(val.iter())
.map(|(&w, &v)| Item::new(w, v))
.collect::<Vec<Item>>();
// 按照单位价值 item.v / item.w 从高到低进行排序
items.sort_by(|a, b| {
(b.v as f64 / b.w as f64)
.partial_cmp(&(a.v as f64 / a.w as f64))
.unwrap()
});
// 循环贪心选择
let mut res = 0.0;
for item in &items {
if item.w <= cap {
// 若剩余容量充足,则将当前物品整个装进背包
res += item.v as f64;
cap -= item.w;
} else {
// 若剩余容量不足,则将当前物品的一部分装进背包
res += item.v as f64 / item.w as f64 * cap as f64;
// 已无剩余容量,因此跳出循环
break;
}
}
res
}
[class]{}-[func]{fractional_knapsack}
```
=== "C"
```c title="fractional_knapsack.c"
/* 物品 */
typedef struct {
int w; // 物品重量
int v; // 物品价值
} Item;
[class]{Item}-[func]{}
/* 分数背包:贪心 */
float fractionalKnapsack(int wgt[], int val[], int itemCount, int cap) {
// 创建物品列表,包含两个属性:重量、价值
Item *items = malloc(sizeof(Item) * itemCount);
for (int i = 0; i < itemCount; i++) {
items[i] = (Item){.w = wgt[i], .v = val[i]};
}
// 按照单位价值 item.v / item.w 从高到低进行排序
qsort(items, (size_t)itemCount, sizeof(Item), sortByValueDensity);
// 循环贪心选择
float res = 0.0;
for (int i = 0; i < itemCount; i++) {
if (items[i].w <= cap) {
// 若剩余容量充足,则将当前物品整个装进背包
res += items[i].v;
cap -= items[i].w;
} else {
// 若剩余容量不足,则将当前物品的一部分装进背包
res += (float)cap / items[i].w * items[i].v;
cap = 0;
break;
}
}
free(items);
return res;
}
[class]{}-[func]{fractionalKnapsack}
```
=== "Kotlin"
```kotlin title="fractional_knapsack.kt"
/* 物品 */
class Item(
val w: Int, // 物品
val v: Int // 物品价值
)
[class]{Item}-[func]{}
/* 分数背包:贪心 */
fun fractionalKnapsack(wgt: IntArray, _val: IntArray, c: Int): Double {
// 创建物品列表,包含两个属性:重量、价值
var cap = c
val items = arrayOfNulls<Item>(wgt.size)
for (i in wgt.indices) {
items[i] = Item(wgt[i], _val[i])
}
// 按照单位价值 item.v / item.w 从高到低进行排序
items.sortBy { item: Item? -> -(item!!.v.toDouble() / item.w) }
// 循环贪心选择
var res = 0.0
for (item in items) {
if (item!!.w <= cap) {
// 若剩余容量充足,则将当前物品整个装进背包
res += item.v
cap -= item.w
} else {
// 若剩余容量不足,则将当前物品的一部分装进背包
res += item.v.toDouble() / item.w * cap
// 已无剩余容量,因此跳出循环
break
}
}
return res
}
[class]{}-[func]{fractionalKnapsack}
```
=== "Ruby"
@@ -509,11 +207,6 @@ We have created an `Item` class in order to sort the items by their unit value.
[class]{}-[func]{fractionalKnapsack}
```
??? pythontutor "Code Visualization"
<div style="height: 549px; width: 100%;"><iframe class="pythontutor-iframe" src="https://pythontutor.com/iframe-embed.html#code=class%20Item%3A%0A%20%20%20%20%22%22%22%E7%89%A9%E5%93%81%22%22%22%0A%20%20%20%20def%20__init__%28self,%20w%3A%20int,%20v%3A%20int%29%3A%0A%20%20%20%20%20%20%20%20self.w%20%3D%20w%20%20%23%20%E7%89%A9%E5%93%81%E9%87%8D%E9%87%8F%0A%20%20%20%20%20%20%20%20self.v%20%3D%20v%20%20%23%20%E7%89%A9%E5%93%81%E4%BB%B7%E5%80%BC%0A%0Adef%20fractional_knapsack%28wgt%3A%20list%5Bint%5D,%20val%3A%20list%5Bint%5D,%20cap%3A%20int%29%20-%3E%20int%3A%0A%20%20%20%20%22%22%22%E5%88%86%E6%95%B0%E8%83%8C%E5%8C%85%EF%BC%9A%E8%B4%AA%E5%BF%83%22%22%22%0A%20%20%20%20%23%20%E5%88%9B%E5%BB%BA%E7%89%A9%E5%93%81%E5%88%97%E8%A1%A8%EF%BC%8C%E5%8C%85%E5%90%AB%E4%B8%A4%E4%B8%AA%E5%B1%9E%E6%80%A7%EF%BC%9A%E9%87%8D%E9%87%8F%E3%80%81%E4%BB%B7%E5%80%BC%0A%20%20%20%20items%20%3D%20%5BItem%28w,%20v%29%20for%20w,%20v%20in%20zip%28wgt,%20val%29%5D%0A%20%20%20%20%23%20%E6%8C%89%E7%85%A7%E5%8D%95%E4%BD%8D%E4%BB%B7%E5%80%BC%20item.v%20/%20item.w%20%E4%BB%8E%E9%AB%98%E5%88%B0%E4%BD%8E%E8%BF%9B%E8%A1%8C%E6%8E%92%E5%BA%8F%0A%20%20%20%20items.sort%28key%3Dlambda%20item%3A%20item.v%20/%20item.w,%20reverse%3DTrue%29%0A%20%20%20%20%23%20%E5%BE%AA%E7%8E%AF%E8%B4%AA%E5%BF%83%E9%80%89%E6%8B%A9%0A%20%20%20%20res%20%3D%200%0A%20%20%20%20for%20item%20in%20items%3A%0A%20%20%20%20%20%20%20%20if%20item.w%20%3C%3D%20cap%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E8%8B%A5%E5%89%A9%E4%BD%99%E5%AE%B9%E9%87%8F%E5%85%85%E8%B6%B3%EF%BC%8C%E5%88%99%E5%B0%86%E5%BD%93%E5%89%8D%E7%89%A9%E5%93%81%E6%95%B4%E4%B8%AA%E8%A3%85%E8%BF%9B%E8%83%8C%E5%8C%85%0A%20%20%20%20%20%20%20%20%20%20%20%20res%20%2B%3D%20item.v%0A%20%20%20%20%20%20%20%20%20%20%20%20cap%20-%3D%20item.w%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E8%8B%A5%E5%89%A9%E4%BD%99%E5%AE%B9%E9%87%8F%E4%B8%8D%E8%B6%B3%EF%BC%8C%E5%88%99%E5%B0%86%E5%BD%93%E5%89%8D%E7%89%A9%E5%93%81%E7%9A%84%E4%B8%80%E9%83%A8%E5%88%86%E8%A3%85%E8%BF%9B%E8%83%8C%E5%8C%85%0A%20%20%20%20%20%20%20%20%20%20%20%20res%20%2B%3D%20%28item.v%20/%20item.w%29%20*%20cap%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E5%B7%B2%E6%97%A0%E5%89%A9%E4%BD%99%E5%AE%B9%E9%87%8F%EF%BC%8C%E5%9B%A0%E6%AD%A4%E8%B7%B3%E5%87%BA%E5%BE%AA%E7%8E%AF%0A%20%20%20%20%20%20%20%20%20%20%20%20break%0A%20%20%20%20return%20res%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20wgt%20%3D%20%5B10,%2020,%2030,%2040,%2050%5D%0A%20%20%20%20val%20%3D%20%5B50,%20120,%20150,%20210,%20240%5D%0A%20%20%20%20cap%20%3D%2050%0A%20%20%20%20n%20%3D%20len%28wgt%29%0A%0A%20%20%20%20%23%20%E8%B4%AA%E5%BF%83%E7%AE%97%E6%B3%95%0A%20%20%20%20res%20%3D%20fractional_knapsack%28wgt,%20val,%20cap%29%0A%20%20%20%20print%28f%22%E4%B8%8D%E8%B6%85%E8%BF%87%E8%83%8C%E5%8C%85%E5%AE%B9%E9%87%8F%E7%9A%84%E6%9C%80%E5%A4%A7%E7%89%A9%E5%93%81%E4%BB%B7%E5%80%BC%E4%B8%BA%20%7Bres%7D%22%29&codeDivHeight=472&codeDivWidth=350&cumulative=false&curInstr=8&heapPrimitives=nevernest&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false"> </iframe></div>
<div style="margin-top: 5px;"><a href="https://pythontutor.com/iframe-embed.html#code=class%20Item%3A%0A%20%20%20%20%22%22%22%E7%89%A9%E5%93%81%22%22%22%0A%20%20%20%20def%20__init__%28self,%20w%3A%20int,%20v%3A%20int%29%3A%0A%20%20%20%20%20%20%20%20self.w%20%3D%20w%20%20%23%20%E7%89%A9%E5%93%81%E9%87%8D%E9%87%8F%0A%20%20%20%20%20%20%20%20self.v%20%3D%20v%20%20%23%20%E7%89%A9%E5%93%81%E4%BB%B7%E5%80%BC%0A%0Adef%20fractional_knapsack%28wgt%3A%20list%5Bint%5D,%20val%3A%20list%5Bint%5D,%20cap%3A%20int%29%20-%3E%20int%3A%0A%20%20%20%20%22%22%22%E5%88%86%E6%95%B0%E8%83%8C%E5%8C%85%EF%BC%9A%E8%B4%AA%E5%BF%83%22%22%22%0A%20%20%20%20%23%20%E5%88%9B%E5%BB%BA%E7%89%A9%E5%93%81%E5%88%97%E8%A1%A8%EF%BC%8C%E5%8C%85%E5%90%AB%E4%B8%A4%E4%B8%AA%E5%B1%9E%E6%80%A7%EF%BC%9A%E9%87%8D%E9%87%8F%E3%80%81%E4%BB%B7%E5%80%BC%0A%20%20%20%20items%20%3D%20%5BItem%28w,%20v%29%20for%20w,%20v%20in%20zip%28wgt,%20val%29%5D%0A%20%20%20%20%23%20%E6%8C%89%E7%85%A7%E5%8D%95%E4%BD%8D%E4%BB%B7%E5%80%BC%20item.v%20/%20item.w%20%E4%BB%8E%E9%AB%98%E5%88%B0%E4%BD%8E%E8%BF%9B%E8%A1%8C%E6%8E%92%E5%BA%8F%0A%20%20%20%20items.sort%28key%3Dlambda%20item%3A%20item.v%20/%20item.w,%20reverse%3DTrue%29%0A%20%20%20%20%23%20%E5%BE%AA%E7%8E%AF%E8%B4%AA%E5%BF%83%E9%80%89%E6%8B%A9%0A%20%20%20%20res%20%3D%200%0A%20%20%20%20for%20item%20in%20items%3A%0A%20%20%20%20%20%20%20%20if%20item.w%20%3C%3D%20cap%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E8%8B%A5%E5%89%A9%E4%BD%99%E5%AE%B9%E9%87%8F%E5%85%85%E8%B6%B3%EF%BC%8C%E5%88%99%E5%B0%86%E5%BD%93%E5%89%8D%E7%89%A9%E5%93%81%E6%95%B4%E4%B8%AA%E8%A3%85%E8%BF%9B%E8%83%8C%E5%8C%85%0A%20%20%20%20%20%20%20%20%20%20%20%20res%20%2B%3D%20item.v%0A%20%20%20%20%20%20%20%20%20%20%20%20cap%20-%3D%20item.w%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E8%8B%A5%E5%89%A9%E4%BD%99%E5%AE%B9%E9%87%8F%E4%B8%8D%E8%B6%B3%EF%BC%8C%E5%88%99%E5%B0%86%E5%BD%93%E5%89%8D%E7%89%A9%E5%93%81%E7%9A%84%E4%B8%80%E9%83%A8%E5%88%86%E8%A3%85%E8%BF%9B%E8%83%8C%E5%8C%85%0A%20%20%20%20%20%20%20%20%20%20%20%20res%20%2B%3D%20%28item.v%20/%20item.w%29%20*%20cap%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E5%B7%B2%E6%97%A0%E5%89%A9%E4%BD%99%E5%AE%B9%E9%87%8F%EF%BC%8C%E5%9B%A0%E6%AD%A4%E8%B7%B3%E5%87%BA%E5%BE%AA%E7%8E%AF%0A%20%20%20%20%20%20%20%20%20%20%20%20break%0A%20%20%20%20return%20res%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20wgt%20%3D%20%5B10,%2020,%2030,%2040,%2050%5D%0A%20%20%20%20val%20%3D%20%5B50,%20120,%20150,%20210,%20240%5D%0A%20%20%20%20cap%20%3D%2050%0A%20%20%20%20n%20%3D%20len%28wgt%29%0A%0A%20%20%20%20%23%20%E8%B4%AA%E5%BF%83%E7%AE%97%E6%B3%95%0A%20%20%20%20res%20%3D%20fractional_knapsack%28wgt,%20val,%20cap%29%0A%20%20%20%20print%28f%22%E4%B8%8D%E8%B6%85%E8%BF%87%E8%83%8C%E5%8C%85%E5%AE%B9%E9%87%8F%E7%9A%84%E6%9C%80%E5%A4%A7%E7%89%A9%E5%93%81%E4%BB%B7%E5%80%BC%E4%B8%BA%20%7Bres%7D%22%29&codeDivHeight=800&codeDivWidth=600&cumulative=false&curInstr=8&heapPrimitives=nevernest&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false" target="_blank" rel="noopener noreferrer">Full Screen ></a></div>
Apart from sorting, in the worst case, the entire list of items needs to be traversed, **hence the time complexity is $O(n)$**, where $n$ is the number of items.
Since an `Item` object list is initialized, **the space complexity is $O(n)$**.

View File

@@ -29,64 +29,47 @@ The implementation code is as follows:
```python title="coin_change_greedy.py"
def coin_change_greedy(coins: list[int], amt: int) -> int:
"""零钱兑换:贪心"""
# 假设 coins 列表有序
"""Coin change: Greedy"""
# Assume coins list is ordered
i = len(coins) - 1
count = 0
# 循环进行贪心选择,直到无剩余金额
# Loop for greedy selection until no remaining amount
while amt > 0:
# 找到小于且最接近剩余金额的硬币
# Find the smallest coin close to and less than the remaining amount
while i > 0 and coins[i] > amt:
i -= 1
# 选择 coins[i]
# Choose coins[i]
amt -= coins[i]
count += 1
# 若未找到可行方案,则返回 -1
# If no feasible solution is found, return -1
return count if amt == 0 else -1
```
=== "C++"
```cpp title="coin_change_greedy.cpp"
/* 零钱兑换:贪心 */
int coinChangeGreedy(vector<int> &coins, int amt) {
// 假设 coins 列表有序
int i = coins.size() - 1;
int count = 0;
// 循环进行贪心选择,直到无剩余金额
while (amt > 0) {
// 找到小于且最接近剩余金额的硬币
while (i > 0 && coins[i] > amt) {
i--;
}
// 选择 coins[i]
amt -= coins[i];
count++;
}
// 若未找到可行方案,则返回 -1
return amt == 0 ? count : -1;
}
[class]{}-[func]{coinChangeGreedy}
```
=== "Java"
```java title="coin_change_greedy.java"
/* 零钱兑换:贪心 */
/* Coin change: Greedy */
int coinChangeGreedy(int[] coins, int amt) {
// 假设 coins 列表有序
// Assume coins list is ordered
int i = coins.length - 1;
int count = 0;
// 循环进行贪心选择,直到无剩余金额
// Loop for greedy selection until no remaining amount
while (amt > 0) {
// 找到小于且最接近剩余金额的硬币
// Find the smallest coin close to and less than the remaining amount
while (i > 0 && coins[i] > amt) {
i--;
}
// 选择 coins[i]
// Choose coins[i]
amt -= coins[i];
count++;
}
// 若未找到可行方案,则返回 -1
// If no feasible solution is found, return -1
return amt == 0 ? count : -1;
}
```
@@ -94,217 +77,55 @@ The implementation code is as follows:
=== "C#"
```csharp title="coin_change_greedy.cs"
/* 零钱兑换:贪心 */
int CoinChangeGreedy(int[] coins, int amt) {
// 假设 coins 列表有序
int i = coins.Length - 1;
int count = 0;
// 循环进行贪心选择,直到无剩余金额
while (amt > 0) {
// 找到小于且最接近剩余金额的硬币
while (i > 0 && coins[i] > amt) {
i--;
}
// 选择 coins[i]
amt -= coins[i];
count++;
}
// 若未找到可行方案,则返回 -1
return amt == 0 ? count : -1;
}
[class]{coin_change_greedy}-[func]{CoinChangeGreedy}
```
=== "Go"
```go title="coin_change_greedy.go"
/* 零钱兑换:贪心 */
func coinChangeGreedy(coins []int, amt int) int {
// 假设 coins 列表有序
i := len(coins) - 1
count := 0
// 循环进行贪心选择,直到无剩余金额
for amt > 0 {
// 找到小于且最接近剩余金额的硬币
for i > 0 && coins[i] > amt {
i--
}
// 选择 coins[i]
amt -= coins[i]
count++
}
// 若未找到可行方案,则返回 -1
if amt != 0 {
return -1
}
return count
}
[class]{}-[func]{coinChangeGreedy}
```
=== "Swift"
```swift title="coin_change_greedy.swift"
/* 零钱兑换:贪心 */
func coinChangeGreedy(coins: [Int], amt: Int) -> Int {
// 假设 coins 列表有序
var i = coins.count - 1
var count = 0
var amt = amt
// 循环进行贪心选择,直到无剩余金额
while amt > 0 {
// 找到小于且最接近剩余金额的硬币
while i > 0 && coins[i] > amt {
i -= 1
}
// 选择 coins[i]
amt -= coins[i]
count += 1
}
// 若未找到可行方案,则返回 -1
return amt == 0 ? count : -1
}
[class]{}-[func]{coinChangeGreedy}
```
=== "JS"
```javascript title="coin_change_greedy.js"
/* 零钱兑换:贪心 */
function coinChangeGreedy(coins, amt) {
// 假设 coins 数组有序
let i = coins.length - 1;
let count = 0;
// 循环进行贪心选择,直到无剩余金额
while (amt > 0) {
// 找到小于且最接近剩余金额的硬币
while (i > 0 && coins[i] > amt) {
i--;
}
// 选择 coins[i]
amt -= coins[i];
count++;
}
// 若未找到可行方案,则返回 -1
return amt === 0 ? count : -1;
}
[class]{}-[func]{coinChangeGreedy}
```
=== "TS"
```typescript title="coin_change_greedy.ts"
/* 零钱兑换:贪心 */
function coinChangeGreedy(coins: number[], amt: number): number {
// 假设 coins 数组有序
let i = coins.length - 1;
let count = 0;
// 循环进行贪心选择,直到无剩余金额
while (amt > 0) {
// 找到小于且最接近剩余金额的硬币
while (i > 0 && coins[i] > amt) {
i--;
}
// 选择 coins[i]
amt -= coins[i];
count++;
}
// 若未找到可行方案,则返回 -1
return amt === 0 ? count : -1;
}
[class]{}-[func]{coinChangeGreedy}
```
=== "Dart"
```dart title="coin_change_greedy.dart"
/* 零钱兑换:贪心 */
int coinChangeGreedy(List<int> coins, int amt) {
// 假设 coins 列表有序
int i = coins.length - 1;
int count = 0;
// 循环进行贪心选择,直到无剩余金额
while (amt > 0) {
// 找到小于且最接近剩余金额的硬币
while (i > 0 && coins[i] > amt) {
i--;
}
// 选择 coins[i]
amt -= coins[i];
count++;
}
// 若未找到可行方案,则返回 -1
return amt == 0 ? count : -1;
}
[class]{}-[func]{coinChangeGreedy}
```
=== "Rust"
```rust title="coin_change_greedy.rs"
/* 零钱兑换:贪心 */
fn coin_change_greedy(coins: &[i32], mut amt: i32) -> i32 {
// 假设 coins 列表有序
let mut i = coins.len() - 1;
let mut count = 0;
// 循环进行贪心选择,直到无剩余金额
while amt > 0 {
// 找到小于且最接近剩余金额的硬币
while i > 0 && coins[i] > amt {
i -= 1;
}
// 选择 coins[i]
amt -= coins[i];
count += 1;
}
// 若未找到可行方案,则返回 -1
if amt == 0 {
count
} else {
-1
}
}
[class]{}-[func]{coin_change_greedy}
```
=== "C"
```c title="coin_change_greedy.c"
/* 零钱兑换:贪心 */
int coinChangeGreedy(int *coins, int size, int amt) {
// 假设 coins 列表有序
int i = size - 1;
int count = 0;
// 循环进行贪心选择,直到无剩余金额
while (amt > 0) {
// 找到小于且最接近剩余金额的硬币
while (i > 0 && coins[i] > amt) {
i--;
}
// 选择 coins[i]
amt -= coins[i];
count++;
}
// 若未找到可行方案,则返回 -1
return amt == 0 ? count : -1;
}
[class]{}-[func]{coinChangeGreedy}
```
=== "Kotlin"
```kotlin title="coin_change_greedy.kt"
/* 零钱兑换:贪心 */
fun coinChangeGreedy(coins: IntArray, amt: Int): Int {
// 假设 coins 列表有序
var am = amt
var i = coins.size - 1
var count = 0
// 循环进行贪心选择,直到无剩余金额
while (am > 0) {
// 找到小于且最接近剩余金额的硬币
while (i > 0 && coins[i] > am) {
i--
}
// 选择 coins[i]
am -= coins[i]
count++
}
// 若未找到可行方案,则返回 -1
return if (am == 0) count else -1
}
[class]{}-[func]{coinChangeGreedy}
```
=== "Ruby"
@@ -319,11 +140,6 @@ The implementation code is as follows:
[class]{}-[func]{coinChangeGreedy}
```
??? pythontutor "Code Visualization"
<div style="height: 549px; width: 100%;"><iframe class="pythontutor-iframe" src="https://pythontutor.com/iframe-embed.html#code=def%20coin_change_greedy%28coins%3A%20list%5Bint%5D,%20amt%3A%20int%29%20-%3E%20int%3A%0A%20%20%20%20%22%22%22%E9%9B%B6%E9%92%B1%E5%85%91%E6%8D%A2%EF%BC%9A%E8%B4%AA%E5%BF%83%22%22%22%0A%20%20%20%20%23%20%E5%81%87%E8%AE%BE%20coins%20%E5%88%97%E8%A1%A8%E6%9C%89%E5%BA%8F%0A%20%20%20%20i%20%3D%20len%28coins%29%20-%201%0A%20%20%20%20count%20%3D%200%0A%20%20%20%20%23%20%E5%BE%AA%E7%8E%AF%E8%BF%9B%E8%A1%8C%E8%B4%AA%E5%BF%83%E9%80%89%E6%8B%A9%EF%BC%8C%E7%9B%B4%E5%88%B0%E6%97%A0%E5%89%A9%E4%BD%99%E9%87%91%E9%A2%9D%0A%20%20%20%20while%20amt%20%3E%200%3A%0A%20%20%20%20%20%20%20%20%23%20%E6%89%BE%E5%88%B0%E5%B0%8F%E4%BA%8E%E4%B8%94%E6%9C%80%E6%8E%A5%E8%BF%91%E5%89%A9%E4%BD%99%E9%87%91%E9%A2%9D%E7%9A%84%E7%A1%AC%E5%B8%81%0A%20%20%20%20%20%20%20%20while%20i%20%3E%200%20and%20coins%5Bi%5D%20%3E%20amt%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20i%20-%3D%201%0A%20%20%20%20%20%20%20%20%23%20%E9%80%89%E6%8B%A9%20coins%5Bi%5D%0A%20%20%20%20%20%20%20%20amt%20-%3D%20coins%5Bi%5D%0A%20%20%20%20%20%20%20%20count%20%2B%3D%201%0A%20%20%20%20%23%20%E8%8B%A5%E6%9C%AA%E6%89%BE%E5%88%B0%E5%8F%AF%E8%A1%8C%E6%96%B9%E6%A1%88%EF%BC%8C%E5%88%99%E8%BF%94%E5%9B%9E%20-1%0A%20%20%20%20return%20count%20if%20amt%20%3D%3D%200%20else%20-1%0A%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%E8%B4%AA%E5%BF%83%EF%BC%9A%E8%83%BD%E5%A4%9F%E4%BF%9D%E8%AF%81%E6%89%BE%E5%88%B0%E5%85%A8%E5%B1%80%E6%9C%80%E4%BC%98%E8%A7%A3%0A%20%20%20%20coins%20%3D%20%5B1,%205,%2010,%2020,%2050,%20100%5D%0A%20%20%20%20amt%20%3D%20186%0A%20%20%20%20res%20%3D%20coin_change_greedy%28coins,%20amt%29%0A%20%20%20%20print%28f%22%5Cncoins%20%3D%20%7Bcoins%7D,%20amt%20%3D%20%7Bamt%7D%22%29%0A%20%20%20%20print%28f%22%E5%87%91%E5%88%B0%20%7Bamt%7D%20%E6%89%80%E9%9C%80%E7%9A%84%E6%9C%80%E5%B0%91%E7%A1%AC%E5%B8%81%E6%95%B0%E9%87%8F%E4%B8%BA%20%7Bres%7D%22%29%0A%0A%20%20%20%20%23%20%E8%B4%AA%E5%BF%83%EF%BC%9A%E6%97%A0%E6%B3%95%E4%BF%9D%E8%AF%81%E6%89%BE%E5%88%B0%E5%85%A8%E5%B1%80%E6%9C%80%E4%BC%98%E8%A7%A3%0A%20%20%20%20coins%20%3D%20%5B1,%2020,%2050%5D%0A%20%20%20%20amt%20%3D%2060%0A%20%20%20%20res%20%3D%20coin_change_greedy%28coins,%20amt%29%0A%20%20%20%20print%28f%22%5Cncoins%20%3D%20%7Bcoins%7D,%20amt%20%3D%20%7Bamt%7D%22%29%0A%20%20%20%20print%28f%22%E5%87%91%E5%88%B0%20%7Bamt%7D%20%E6%89%80%E9%9C%80%E7%9A%84%E6%9C%80%E5%B0%91%E7%A1%AC%E5%B8%81%E6%95%B0%E9%87%8F%E4%B8%BA%20%7Bres%7D%22%29%0A%20%20%20%20print%28f%22%E5%AE%9E%E9%99%85%E4%B8%8A%E9%9C%80%E8%A6%81%E7%9A%84%E6%9C%80%E5%B0%91%E6%95%B0%E9%87%8F%E4%B8%BA%203%20%EF%BC%8C%E5%8D%B3%2020%20%2B%2020%20%2B%2020%22%29&codeDivHeight=472&codeDivWidth=350&cumulative=false&curInstr=5&heapPrimitives=nevernest&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false"> </iframe></div>
<div style="margin-top: 5px;"><a href="https://pythontutor.com/iframe-embed.html#code=def%20coin_change_greedy%28coins%3A%20list%5Bint%5D,%20amt%3A%20int%29%20-%3E%20int%3A%0A%20%20%20%20%22%22%22%E9%9B%B6%E9%92%B1%E5%85%91%E6%8D%A2%EF%BC%9A%E8%B4%AA%E5%BF%83%22%22%22%0A%20%20%20%20%23%20%E5%81%87%E8%AE%BE%20coins%20%E5%88%97%E8%A1%A8%E6%9C%89%E5%BA%8F%0A%20%20%20%20i%20%3D%20len%28coins%29%20-%201%0A%20%20%20%20count%20%3D%200%0A%20%20%20%20%23%20%E5%BE%AA%E7%8E%AF%E8%BF%9B%E8%A1%8C%E8%B4%AA%E5%BF%83%E9%80%89%E6%8B%A9%EF%BC%8C%E7%9B%B4%E5%88%B0%E6%97%A0%E5%89%A9%E4%BD%99%E9%87%91%E9%A2%9D%0A%20%20%20%20while%20amt%20%3E%200%3A%0A%20%20%20%20%20%20%20%20%23%20%E6%89%BE%E5%88%B0%E5%B0%8F%E4%BA%8E%E4%B8%94%E6%9C%80%E6%8E%A5%E8%BF%91%E5%89%A9%E4%BD%99%E9%87%91%E9%A2%9D%E7%9A%84%E7%A1%AC%E5%B8%81%0A%20%20%20%20%20%20%20%20while%20i%20%3E%200%20and%20coins%5Bi%5D%20%3E%20amt%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20i%20-%3D%201%0A%20%20%20%20%20%20%20%20%23%20%E9%80%89%E6%8B%A9%20coins%5Bi%5D%0A%20%20%20%20%20%20%20%20amt%20-%3D%20coins%5Bi%5D%0A%20%20%20%20%20%20%20%20count%20%2B%3D%201%0A%20%20%20%20%23%20%E8%8B%A5%E6%9C%AA%E6%89%BE%E5%88%B0%E5%8F%AF%E8%A1%8C%E6%96%B9%E6%A1%88%EF%BC%8C%E5%88%99%E8%BF%94%E5%9B%9E%20-1%0A%20%20%20%20return%20count%20if%20amt%20%3D%3D%200%20else%20-1%0A%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%E8%B4%AA%E5%BF%83%EF%BC%9A%E8%83%BD%E5%A4%9F%E4%BF%9D%E8%AF%81%E6%89%BE%E5%88%B0%E5%85%A8%E5%B1%80%E6%9C%80%E4%BC%98%E8%A7%A3%0A%20%20%20%20coins%20%3D%20%5B1,%205,%2010,%2020,%2050,%20100%5D%0A%20%20%20%20amt%20%3D%20186%0A%20%20%20%20res%20%3D%20coin_change_greedy%28coins,%20amt%29%0A%20%20%20%20print%28f%22%5Cncoins%20%3D%20%7Bcoins%7D,%20amt%20%3D%20%7Bamt%7D%22%29%0A%20%20%20%20print%28f%22%E5%87%91%E5%88%B0%20%7Bamt%7D%20%E6%89%80%E9%9C%80%E7%9A%84%E6%9C%80%E5%B0%91%E7%A1%AC%E5%B8%81%E6%95%B0%E9%87%8F%E4%B8%BA%20%7Bres%7D%22%29%0A%0A%20%20%20%20%23%20%E8%B4%AA%E5%BF%83%EF%BC%9A%E6%97%A0%E6%B3%95%E4%BF%9D%E8%AF%81%E6%89%BE%E5%88%B0%E5%85%A8%E5%B1%80%E6%9C%80%E4%BC%98%E8%A7%A3%0A%20%20%20%20coins%20%3D%20%5B1,%2020,%2050%5D%0A%20%20%20%20amt%20%3D%2060%0A%20%20%20%20res%20%3D%20coin_change_greedy%28coins,%20amt%29%0A%20%20%20%20print%28f%22%5Cncoins%20%3D%20%7Bcoins%7D,%20amt%20%3D%20%7Bamt%7D%22%29%0A%20%20%20%20print%28f%22%E5%87%91%E5%88%B0%20%7Bamt%7D%20%E6%89%80%E9%9C%80%E7%9A%84%E6%9C%80%E5%B0%91%E7%A1%AC%E5%B8%81%E6%95%B0%E9%87%8F%E4%B8%BA%20%7Bres%7D%22%29%0A%20%20%20%20print%28f%22%E5%AE%9E%E9%99%85%E4%B8%8A%E9%9C%80%E8%A6%81%E7%9A%84%E6%9C%80%E5%B0%91%E6%95%B0%E9%87%8F%E4%B8%BA%203%20%EF%BC%8C%E5%8D%B3%2020%20%2B%2020%20%2B%2020%22%29&codeDivHeight=800&codeDivWidth=600&cumulative=false&curInstr=5&heapPrimitives=nevernest&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false" target="_blank" rel="noopener noreferrer">Full Screen ></a></div>
You might exclaim: So clean! The greedy algorithm solves the coin change problem in about ten lines of code.
## 15.1.1 &nbsp; Advantages and limitations of greedy algorithms

View File

@@ -96,17 +96,17 @@ The variables $i$, $j$, and $res$ use a constant amount of extra space, **thus t
```python title="max_capacity.py"
def max_capacity(ht: list[int]) -> int:
"""最大容量:贪心"""
# 初始化 i, j使其分列数组两端
"""Maximum capacity: Greedy"""
# Initialize i, j, making them split the array at both ends
i, j = 0, len(ht) - 1
# 初始最大容量为 0
# Initial maximum capacity is 0
res = 0
# 循环贪心选择,直至两板相遇
# Loop for greedy selection until the two boards meet
while i < j:
# 更新最大容量
# Update maximum capacity
cap = min(ht[i], ht[j]) * (j - i)
res = max(res, cap)
# 向内移动短板
# Move the shorter board inward
if ht[i] < ht[j]:
i += 1
else:
@@ -117,43 +117,24 @@ The variables $i$, $j$, and $res$ use a constant amount of extra space, **thus t
=== "C++"
```cpp title="max_capacity.cpp"
/* 最大容量:贪心 */
int maxCapacity(vector<int> &ht) {
// 初始化 i, j使其分列数组两端
int i = 0, j = ht.size() - 1;
// 初始最大容量为 0
int res = 0;
// 循环贪心选择,直至两板相遇
while (i < j) {
// 更新最大容量
int cap = min(ht[i], ht[j]) * (j - i);
res = max(res, cap);
// 向内移动短板
if (ht[i] < ht[j]) {
i++;
} else {
j--;
}
}
return res;
}
[class]{}-[func]{maxCapacity}
```
=== "Java"
```java title="max_capacity.java"
/* 最大容量:贪心 */
/* Maximum capacity: Greedy */
int maxCapacity(int[] ht) {
// 初始化 i, j使其分列数组两端
// Initialize i, j, making them split the array at both ends
int i = 0, j = ht.length - 1;
// 初始最大容量为 0
// Initial maximum capacity is 0
int res = 0;
// 循环贪心选择,直至两板相遇
// Loop for greedy selection until the two boards meet
while (i < j) {
// 更新最大容量
// Update maximum capacity
int cap = Math.min(ht[i], ht[j]) * (j - i);
res = Math.max(res, cap);
// 向内移动短板
// Move the shorter board inward
if (ht[i] < ht[j]) {
i++;
} else {
@@ -167,231 +148,55 @@ The variables $i$, $j$, and $res$ use a constant amount of extra space, **thus t
=== "C#"
```csharp title="max_capacity.cs"
/* 最大容量:贪心 */
int MaxCapacity(int[] ht) {
// 初始化 i, j使其分列数组两端
int i = 0, j = ht.Length - 1;
// 初始最大容量为 0
int res = 0;
// 循环贪心选择,直至两板相遇
while (i < j) {
// 更新最大容量
int cap = Math.Min(ht[i], ht[j]) * (j - i);
res = Math.Max(res, cap);
// 向内移动短板
if (ht[i] < ht[j]) {
i++;
} else {
j--;
}
}
return res;
}
[class]{max_capacity}-[func]{MaxCapacity}
```
=== "Go"
```go title="max_capacity.go"
/* 最大容量:贪心 */
func maxCapacity(ht []int) int {
// 初始化 i, j使其分列数组两端
i, j := 0, len(ht)-1
// 初始最大容量为 0
res := 0
// 循环贪心选择,直至两板相遇
for i < j {
// 更新最大容量
capacity := int(math.Min(float64(ht[i]), float64(ht[j]))) * (j - i)
res = int(math.Max(float64(res), float64(capacity)))
// 向内移动短板
if ht[i] < ht[j] {
i++
} else {
j--
}
}
return res
}
[class]{}-[func]{maxCapacity}
```
=== "Swift"
```swift title="max_capacity.swift"
/* 最大容量:贪心 */
func maxCapacity(ht: [Int]) -> Int {
// 初始化 i, j使其分列数组两端
var i = ht.startIndex, j = ht.endIndex - 1
// 初始最大容量为 0
var res = 0
// 循环贪心选择,直至两板相遇
while i < j {
// 更新最大容量
let cap = min(ht[i], ht[j]) * (j - i)
res = max(res, cap)
// 向内移动短板
if ht[i] < ht[j] {
i += 1
} else {
j -= 1
}
}
return res
}
[class]{}-[func]{maxCapacity}
```
=== "JS"
```javascript title="max_capacity.js"
/* 最大容量:贪心 */
function maxCapacity(ht) {
// 初始化 i, j使其分列数组两端
let i = 0,
j = ht.length - 1;
// 初始最大容量为 0
let res = 0;
// 循环贪心选择,直至两板相遇
while (i < j) {
// 更新最大容量
const cap = Math.min(ht[i], ht[j]) * (j - i);
res = Math.max(res, cap);
// 向内移动短板
if (ht[i] < ht[j]) {
i += 1;
} else {
j -= 1;
}
}
return res;
}
[class]{}-[func]{maxCapacity}
```
=== "TS"
```typescript title="max_capacity.ts"
/* 最大容量:贪心 */
function maxCapacity(ht: number[]): number {
// 初始化 i, j使其分列数组两端
let i = 0,
j = ht.length - 1;
// 初始最大容量为 0
let res = 0;
// 循环贪心选择,直至两板相遇
while (i < j) {
// 更新最大容量
const cap: number = Math.min(ht[i], ht[j]) * (j - i);
res = Math.max(res, cap);
// 向内移动短板
if (ht[i] < ht[j]) {
i += 1;
} else {
j -= 1;
}
}
return res;
}
[class]{}-[func]{maxCapacity}
```
=== "Dart"
```dart title="max_capacity.dart"
/* 最大容量:贪心 */
int maxCapacity(List<int> ht) {
// 初始化 i, j使其分列数组两端
int i = 0, j = ht.length - 1;
// 初始最大容量为 0
int res = 0;
// 循环贪心选择,直至两板相遇
while (i < j) {
// 更新最大容量
int cap = min(ht[i], ht[j]) * (j - i);
res = max(res, cap);
// 向内移动短板
if (ht[i] < ht[j]) {
i++;
} else {
j--;
}
}
return res;
}
[class]{}-[func]{maxCapacity}
```
=== "Rust"
```rust title="max_capacity.rs"
/* 最大容量:贪心 */
fn max_capacity(ht: &[i32]) -> i32 {
// 初始化 i, j使其分列数组两端
let mut i = 0;
let mut j = ht.len() - 1;
// 初始最大容量为 0
let mut res = 0;
// 循环贪心选择,直至两板相遇
while i < j {
// 更新最大容量
let cap = std::cmp::min(ht[i], ht[j]) * (j - i) as i32;
res = std::cmp::max(res, cap);
// 向内移动短板
if ht[i] < ht[j] {
i += 1;
} else {
j -= 1;
}
}
res
}
[class]{}-[func]{max_capacity}
```
=== "C"
```c title="max_capacity.c"
/* 最大容量:贪心 */
int maxCapacity(int ht[], int htLength) {
// 初始化 i, j使其分列数组两端
int i = 0;
int j = htLength - 1;
// 初始最大容量为 0
int res = 0;
// 循环贪心选择,直至两板相遇
while (i < j) {
// 更新最大容量
int capacity = myMin(ht[i], ht[j]) * (j - i);
res = myMax(res, capacity);
// 向内移动短板
if (ht[i] < ht[j]) {
i++;
} else {
j--;
}
}
return res;
}
[class]{}-[func]{maxCapacity}
```
=== "Kotlin"
```kotlin title="max_capacity.kt"
/* 最大容量:贪心 */
fun maxCapacity(ht: IntArray): Int {
// 初始化 i, j使其分列数组两端
var i = 0
var j = ht.size - 1
// 初始最大容量为 0
var res = 0
// 循环贪心选择,直至两板相遇
while (i < j) {
// 更新最大容量
val cap = min(ht[i], ht[j]) * (j - i)
res = max(res, cap)
// 向内移动短板
if (ht[i] < ht[j]) {
i++
} else {
j--
}
}
return res
}
[class]{}-[func]{maxCapacity}
```
=== "Ruby"
@@ -406,11 +211,6 @@ The variables $i$, $j$, and $res$ use a constant amount of extra space, **thus t
[class]{}-[func]{maxCapacity}
```
??? pythontutor "Code Visualization"
<div style="height: 549px; width: 100%;"><iframe class="pythontutor-iframe" src="https://pythontutor.com/iframe-embed.html#code=def%20max_capacity%28ht%3A%20list%5Bint%5D%29%20-%3E%20int%3A%0A%20%20%20%20%22%22%22%E6%9C%80%E5%A4%A7%E5%AE%B9%E9%87%8F%EF%BC%9A%E8%B4%AA%E5%BF%83%22%22%22%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%20i,%20j%EF%BC%8C%E4%BD%BF%E5%85%B6%E5%88%86%E5%88%97%E6%95%B0%E7%BB%84%E4%B8%A4%E7%AB%AF%0A%20%20%20%20i,%20j%20%3D%200,%20len%28ht%29%20-%201%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E6%9C%80%E5%A4%A7%E5%AE%B9%E9%87%8F%E4%B8%BA%200%0A%20%20%20%20res%20%3D%200%0A%20%20%20%20%23%20%E5%BE%AA%E7%8E%AF%E8%B4%AA%E5%BF%83%E9%80%89%E6%8B%A9%EF%BC%8C%E7%9B%B4%E8%87%B3%E4%B8%A4%E6%9D%BF%E7%9B%B8%E9%81%87%0A%20%20%20%20while%20i%20%3C%20j%3A%0A%20%20%20%20%20%20%20%20%23%20%E6%9B%B4%E6%96%B0%E6%9C%80%E5%A4%A7%E5%AE%B9%E9%87%8F%0A%20%20%20%20%20%20%20%20cap%20%3D%20min%28ht%5Bi%5D,%20ht%5Bj%5D%29%20*%20%28j%20-%20i%29%0A%20%20%20%20%20%20%20%20res%20%3D%20max%28res,%20cap%29%0A%20%20%20%20%20%20%20%20%23%20%E5%90%91%E5%86%85%E7%A7%BB%E5%8A%A8%E7%9F%AD%E6%9D%BF%0A%20%20%20%20%20%20%20%20if%20ht%5Bi%5D%20%3C%20ht%5Bj%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20i%20%2B%3D%201%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20j%20-%3D%201%0A%20%20%20%20return%20res%0A%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20ht%20%3D%20%5B3,%208,%205,%202,%207,%207,%203,%204%5D%0A%0A%20%20%20%20%23%20%E8%B4%AA%E5%BF%83%E7%AE%97%E6%B3%95%0A%20%20%20%20res%20%3D%20max_capacity%28ht%29%0A%20%20%20%20print%28f%22%E6%9C%80%E5%A4%A7%E5%AE%B9%E9%87%8F%E4%B8%BA%20%7Bres%7D%22%29&codeDivHeight=472&codeDivWidth=350&cumulative=false&curInstr=4&heapPrimitives=nevernest&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false"> </iframe></div>
<div style="margin-top: 5px;"><a href="https://pythontutor.com/iframe-embed.html#code=def%20max_capacity%28ht%3A%20list%5Bint%5D%29%20-%3E%20int%3A%0A%20%20%20%20%22%22%22%E6%9C%80%E5%A4%A7%E5%AE%B9%E9%87%8F%EF%BC%9A%E8%B4%AA%E5%BF%83%22%22%22%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%20i,%20j%EF%BC%8C%E4%BD%BF%E5%85%B6%E5%88%86%E5%88%97%E6%95%B0%E7%BB%84%E4%B8%A4%E7%AB%AF%0A%20%20%20%20i,%20j%20%3D%200,%20len%28ht%29%20-%201%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E6%9C%80%E5%A4%A7%E5%AE%B9%E9%87%8F%E4%B8%BA%200%0A%20%20%20%20res%20%3D%200%0A%20%20%20%20%23%20%E5%BE%AA%E7%8E%AF%E8%B4%AA%E5%BF%83%E9%80%89%E6%8B%A9%EF%BC%8C%E7%9B%B4%E8%87%B3%E4%B8%A4%E6%9D%BF%E7%9B%B8%E9%81%87%0A%20%20%20%20while%20i%20%3C%20j%3A%0A%20%20%20%20%20%20%20%20%23%20%E6%9B%B4%E6%96%B0%E6%9C%80%E5%A4%A7%E5%AE%B9%E9%87%8F%0A%20%20%20%20%20%20%20%20cap%20%3D%20min%28ht%5Bi%5D,%20ht%5Bj%5D%29%20*%20%28j%20-%20i%29%0A%20%20%20%20%20%20%20%20res%20%3D%20max%28res,%20cap%29%0A%20%20%20%20%20%20%20%20%23%20%E5%90%91%E5%86%85%E7%A7%BB%E5%8A%A8%E7%9F%AD%E6%9D%BF%0A%20%20%20%20%20%20%20%20if%20ht%5Bi%5D%20%3C%20ht%5Bj%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20i%20%2B%3D%201%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20j%20-%3D%201%0A%20%20%20%20return%20res%0A%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20ht%20%3D%20%5B3,%208,%205,%202,%207,%207,%203,%204%5D%0A%0A%20%20%20%20%23%20%E8%B4%AA%E5%BF%83%E7%AE%97%E6%B3%95%0A%20%20%20%20res%20%3D%20max_capacity%28ht%29%0A%20%20%20%20print%28f%22%E6%9C%80%E5%A4%A7%E5%AE%B9%E9%87%8F%E4%B8%BA%20%7Bres%7D%22%29&codeDivHeight=800&codeDivWidth=600&cumulative=false&curInstr=4&heapPrimitives=nevernest&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false" target="_blank" rel="noopener noreferrer">Full Screen ></a></div>
### 3. &nbsp; Proof of correctness
The reason why the greedy method is faster than enumeration is that each round of greedy selection "skips" some states.

View File

@@ -77,68 +77,49 @@ Please note, for the boundary case where $n \leq 3$, a $1$ must be split out, wi
```python title="max_product_cutting.py"
def max_product_cutting(n: int) -> int:
"""最大切分乘积:贪心"""
# n <= 3 时,必须切分出一个 1
"""Maximum product of cutting: Greedy"""
# When n <= 3, must cut out a 1
if n <= 3:
return 1 * (n - 1)
# 贪心地切分出 3 a 为 3 的个数b 为余数
# Greedy cut out 3s, a is the number of 3s, b is the remainder
a, b = n // 3, n % 3
if b == 1:
# 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
# When the remainder is 1, convert a pair of 1 * 3 into 2 * 2
return int(math.pow(3, a - 1)) * 2 * 2
if b == 2:
# 当余数为 2 时,不做处理
# When the remainder is 2, do nothing
return int(math.pow(3, a)) * 2
# 当余数为 0 时,不做处理
# When the remainder is 0, do nothing
return int(math.pow(3, a))
```
=== "C++"
```cpp title="max_product_cutting.cpp"
/* 最大切分乘积:贪心 */
int maxProductCutting(int n) {
// 当 n <= 3 时,必须切分出一个 1
if (n <= 3) {
return 1 * (n - 1);
}
// 贪心地切分出 3 a 为 3 的个数b 为余数
int a = n / 3;
int b = n % 3;
if (b == 1) {
// 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
return (int)pow(3, a - 1) * 2 * 2;
}
if (b == 2) {
// 当余数为 2 时,不做处理
return (int)pow(3, a) * 2;
}
// 当余数为 0 时,不做处理
return (int)pow(3, a);
}
[class]{}-[func]{maxProductCutting}
```
=== "Java"
```java title="max_product_cutting.java"
/* 最大切分乘积:贪心 */
/* Maximum product of cutting: Greedy */
int maxProductCutting(int n) {
// n <= 3 时,必须切分出一个 1
// When n <= 3, must cut out a 1
if (n <= 3) {
return 1 * (n - 1);
}
// 贪心地切分出 3 a 为 3 的个数b 为余数
// Greedy cut out 3s, a is the number of 3s, b is the remainder
int a = n / 3;
int b = n % 3;
if (b == 1) {
// 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
// When the remainder is 1, convert a pair of 1 * 3 into 2 * 2
return (int) Math.pow(3, a - 1) * 2 * 2;
}
if (b == 2) {
// 当余数为 2 时,不做处理
// When the remainder is 2, do nothing
return (int) Math.pow(3, a) * 2;
}
// 当余数为 0 时,不做处理
// When the remainder is 0, do nothing
return (int) Math.pow(3, a);
}
```
@@ -146,226 +127,55 @@ Please note, for the boundary case where $n \leq 3$, a $1$ must be split out, wi
=== "C#"
```csharp title="max_product_cutting.cs"
/* 最大切分乘积:贪心 */
int MaxProductCutting(int n) {
// 当 n <= 3 时,必须切分出一个 1
if (n <= 3) {
return 1 * (n - 1);
}
// 贪心地切分出 3 a 为 3 的个数b 为余数
int a = n / 3;
int b = n % 3;
if (b == 1) {
// 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
return (int)Math.Pow(3, a - 1) * 2 * 2;
}
if (b == 2) {
// 当余数为 2 时,不做处理
return (int)Math.Pow(3, a) * 2;
}
// 当余数为 0 时,不做处理
return (int)Math.Pow(3, a);
}
[class]{max_product_cutting}-[func]{MaxProductCutting}
```
=== "Go"
```go title="max_product_cutting.go"
/* 最大切分乘积:贪心 */
func maxProductCutting(n int) int {
// 当 n <= 3 时,必须切分出一个 1
if n <= 3 {
return 1 * (n - 1)
}
// 贪心地切分出 3 a 为 3 的个数b 为余数
a := n / 3
b := n % 3
if b == 1 {
// 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
return int(math.Pow(3, float64(a-1))) * 2 * 2
}
if b == 2 {
// 当余数为 2 时,不做处理
return int(math.Pow(3, float64(a))) * 2
}
// 当余数为 0 时,不做处理
return int(math.Pow(3, float64(a)))
}
[class]{}-[func]{maxProductCutting}
```
=== "Swift"
```swift title="max_product_cutting.swift"
/* 最大切分乘积:贪心 */
func maxProductCutting(n: Int) -> Int {
// 当 n <= 3 时,必须切分出一个 1
if n <= 3 {
return 1 * (n - 1)
}
// 贪心地切分出 3 a 为 3 的个数b 为余数
let a = n / 3
let b = n % 3
if b == 1 {
// 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
return pow(3, a - 1) * 2 * 2
}
if b == 2 {
// 当余数为 2 时,不做处理
return pow(3, a) * 2
}
// 当余数为 0 时,不做处理
return pow(3, a)
}
[class]{}-[func]{maxProductCutting}
```
=== "JS"
```javascript title="max_product_cutting.js"
/* 最大切分乘积:贪心 */
function maxProductCutting(n) {
// 当 n <= 3 时,必须切分出一个 1
if (n <= 3) {
return 1 * (n - 1);
}
// 贪心地切分出 3 a 为 3 的个数b 为余数
let a = Math.floor(n / 3);
let b = n % 3;
if (b === 1) {
// 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
return Math.pow(3, a - 1) * 2 * 2;
}
if (b === 2) {
// 当余数为 2 时,不做处理
return Math.pow(3, a) * 2;
}
// 当余数为 0 时,不做处理
return Math.pow(3, a);
}
[class]{}-[func]{maxProductCutting}
```
=== "TS"
```typescript title="max_product_cutting.ts"
/* 最大切分乘积:贪心 */
function maxProductCutting(n: number): number {
// 当 n <= 3 时,必须切分出一个 1
if (n <= 3) {
return 1 * (n - 1);
}
// 贪心地切分出 3 a 为 3 的个数b 为余数
let a: number = Math.floor(n / 3);
let b: number = n % 3;
if (b === 1) {
// 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
return Math.pow(3, a - 1) * 2 * 2;
}
if (b === 2) {
// 当余数为 2 时,不做处理
return Math.pow(3, a) * 2;
}
// 当余数为 0 时,不做处理
return Math.pow(3, a);
}
[class]{}-[func]{maxProductCutting}
```
=== "Dart"
```dart title="max_product_cutting.dart"
/* 最大切分乘积:贪心 */
int maxProductCutting(int n) {
// 当 n <= 3 时,必须切分出一个 1
if (n <= 3) {
return 1 * (n - 1);
}
// 贪心地切分出 3 a 为 3 的个数b 为余数
int a = n ~/ 3;
int b = n % 3;
if (b == 1) {
// 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
return (pow(3, a - 1) * 2 * 2).toInt();
}
if (b == 2) {
// 当余数为 2 时,不做处理
return (pow(3, a) * 2).toInt();
}
// 当余数为 0 时,不做处理
return pow(3, a).toInt();
}
[class]{}-[func]{maxProductCutting}
```
=== "Rust"
```rust title="max_product_cutting.rs"
/* 最大切分乘积:贪心 */
fn max_product_cutting(n: i32) -> i32 {
// 当 n <= 3 时,必须切分出一个 1
if n <= 3 {
return 1 * (n - 1);
}
// 贪心地切分出 3 a 为 3 的个数b 为余数
let a = n / 3;
let b = n % 3;
if b == 1 {
// 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
3_i32.pow(a as u32 - 1) * 2 * 2
} else if b == 2 {
// 当余数为 2 时,不做处理
3_i32.pow(a as u32) * 2
} else {
// 当余数为 0 时,不做处理
3_i32.pow(a as u32)
}
}
[class]{}-[func]{max_product_cutting}
```
=== "C"
```c title="max_product_cutting.c"
/* 最大切分乘积:贪心 */
int maxProductCutting(int n) {
// 当 n <= 3 时,必须切分出一个 1
if (n <= 3) {
return 1 * (n - 1);
}
// 贪心地切分出 3 a 为 3 的个数b 为余数
int a = n / 3;
int b = n % 3;
if (b == 1) {
// 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
return pow(3, a - 1) * 2 * 2;
}
if (b == 2) {
// 当余数为 2 时,不做处理
return pow(3, a) * 2;
}
// 当余数为 0 时,不做处理
return pow(3, a);
}
[class]{}-[func]{maxProductCutting}
```
=== "Kotlin"
```kotlin title="max_product_cutting.kt"
/* 最大切分乘积:贪心 */
fun maxProductCutting(n: Int): Int {
// 当 n <= 3 时,必须切分出一个 1
if (n <= 3) {
return 1 * (n - 1)
}
// 贪心地切分出 3 a 为 3 的个数b 为余数
val a = n / 3
val b = n % 3
if (b == 1) {
// 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
return 3.0.pow((a - 1)).toInt() * 2 * 2
}
if (b == 2) {
// 当余数为 2 时,不做处理
return 3.0.pow(a).toInt() * 2 * 2
}
// 当余数为 0 时,不做处理
return 3.0.pow(a).toInt()
}
[class]{}-[func]{maxProductCutting}
```
=== "Ruby"
@@ -380,11 +190,6 @@ Please note, for the boundary case where $n \leq 3$, a $1$ must be split out, wi
[class]{}-[func]{maxProductCutting}
```
??? pythontutor "Code Visualization"
<div style="height: 549px; width: 100%;"><iframe class="pythontutor-iframe" src="https://pythontutor.com/iframe-embed.html#code=import%20math%0A%0Adef%20max_product_cutting%28n%3A%20int%29%20-%3E%20int%3A%0A%20%20%20%20%22%22%22%E6%9C%80%E5%A4%A7%E5%88%87%E5%88%86%E4%B9%98%E7%A7%AF%EF%BC%9A%E8%B4%AA%E5%BF%83%22%22%22%0A%20%20%20%20%23%20%E5%BD%93%20n%20%3C%3D%203%20%E6%97%B6%EF%BC%8C%E5%BF%85%E9%A1%BB%E5%88%87%E5%88%86%E5%87%BA%E4%B8%80%E4%B8%AA%201%0A%20%20%20%20if%20n%20%3C%3D%203%3A%0A%20%20%20%20%20%20%20%20return%201%20*%20%28n%20-%201%29%0A%20%20%20%20%23%20%E8%B4%AA%E5%BF%83%E5%9C%B0%E5%88%87%E5%88%86%E5%87%BA%203%20%EF%BC%8Ca%20%E4%B8%BA%203%20%E7%9A%84%E4%B8%AA%E6%95%B0%EF%BC%8Cb%20%E4%B8%BA%E4%BD%99%E6%95%B0%0A%20%20%20%20a,%20b%20%3D%20n%20//%203,%20n%20%25%203%0A%20%20%20%20if%20b%20%3D%3D%201%3A%0A%20%20%20%20%20%20%20%20%23%20%E5%BD%93%E4%BD%99%E6%95%B0%E4%B8%BA%201%20%E6%97%B6%EF%BC%8C%E5%B0%86%E4%B8%80%E5%AF%B9%201%20*%203%20%E8%BD%AC%E5%8C%96%E4%B8%BA%202%20*%202%0A%20%20%20%20%20%20%20%20return%20int%28math.pow%283,%20a%20-%201%29%29%20*%202%20*%202%0A%20%20%20%20if%20b%20%3D%3D%202%3A%0A%20%20%20%20%20%20%20%20%23%20%E5%BD%93%E4%BD%99%E6%95%B0%E4%B8%BA%202%20%E6%97%B6%EF%BC%8C%E4%B8%8D%E5%81%9A%E5%A4%84%E7%90%86%0A%20%20%20%20%20%20%20%20return%20int%28math.pow%283,%20a%29%29%20*%202%0A%20%20%20%20%23%20%E5%BD%93%E4%BD%99%E6%95%B0%E4%B8%BA%200%20%E6%97%B6%EF%BC%8C%E4%B8%8D%E5%81%9A%E5%A4%84%E7%90%86%0A%20%20%20%20return%20int%28math.pow%283,%20a%29%29%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20n%20%3D%2058%0A%0A%20%20%20%20%23%20%E8%B4%AA%E5%BF%83%E7%AE%97%E6%B3%95%0A%20%20%20%20res%20%3D%20max_product_cutting%28n%29%0A%20%20%20%20print%28f%22%E6%9C%80%E5%A4%A7%E5%88%87%E5%88%86%E4%B9%98%E7%A7%AF%E4%B8%BA%20%7Bres%7D%22%29&codeDivHeight=472&codeDivWidth=350&cumulative=false&curInstr=5&heapPrimitives=nevernest&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false"> </iframe></div>
<div style="margin-top: 5px;"><a href="https://pythontutor.com/iframe-embed.html#code=import%20math%0A%0Adef%20max_product_cutting%28n%3A%20int%29%20-%3E%20int%3A%0A%20%20%20%20%22%22%22%E6%9C%80%E5%A4%A7%E5%88%87%E5%88%86%E4%B9%98%E7%A7%AF%EF%BC%9A%E8%B4%AA%E5%BF%83%22%22%22%0A%20%20%20%20%23%20%E5%BD%93%20n%20%3C%3D%203%20%E6%97%B6%EF%BC%8C%E5%BF%85%E9%A1%BB%E5%88%87%E5%88%86%E5%87%BA%E4%B8%80%E4%B8%AA%201%0A%20%20%20%20if%20n%20%3C%3D%203%3A%0A%20%20%20%20%20%20%20%20return%201%20*%20%28n%20-%201%29%0A%20%20%20%20%23%20%E8%B4%AA%E5%BF%83%E5%9C%B0%E5%88%87%E5%88%86%E5%87%BA%203%20%EF%BC%8Ca%20%E4%B8%BA%203%20%E7%9A%84%E4%B8%AA%E6%95%B0%EF%BC%8Cb%20%E4%B8%BA%E4%BD%99%E6%95%B0%0A%20%20%20%20a,%20b%20%3D%20n%20//%203,%20n%20%25%203%0A%20%20%20%20if%20b%20%3D%3D%201%3A%0A%20%20%20%20%20%20%20%20%23%20%E5%BD%93%E4%BD%99%E6%95%B0%E4%B8%BA%201%20%E6%97%B6%EF%BC%8C%E5%B0%86%E4%B8%80%E5%AF%B9%201%20*%203%20%E8%BD%AC%E5%8C%96%E4%B8%BA%202%20*%202%0A%20%20%20%20%20%20%20%20return%20int%28math.pow%283,%20a%20-%201%29%29%20*%202%20*%202%0A%20%20%20%20if%20b%20%3D%3D%202%3A%0A%20%20%20%20%20%20%20%20%23%20%E5%BD%93%E4%BD%99%E6%95%B0%E4%B8%BA%202%20%E6%97%B6%EF%BC%8C%E4%B8%8D%E5%81%9A%E5%A4%84%E7%90%86%0A%20%20%20%20%20%20%20%20return%20int%28math.pow%283,%20a%29%29%20*%202%0A%20%20%20%20%23%20%E5%BD%93%E4%BD%99%E6%95%B0%E4%B8%BA%200%20%E6%97%B6%EF%BC%8C%E4%B8%8D%E5%81%9A%E5%A4%84%E7%90%86%0A%20%20%20%20return%20int%28math.pow%283,%20a%29%29%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20n%20%3D%2058%0A%0A%20%20%20%20%23%20%E8%B4%AA%E5%BF%83%E7%AE%97%E6%B3%95%0A%20%20%20%20res%20%3D%20max_product_cutting%28n%29%0A%20%20%20%20print%28f%22%E6%9C%80%E5%A4%A7%E5%88%87%E5%88%86%E4%B9%98%E7%A7%AF%E4%B8%BA%20%7Bres%7D%22%29&codeDivHeight=800&codeDivWidth=600&cumulative=false&curInstr=5&heapPrimitives=nevernest&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false" target="_blank" rel="noopener noreferrer">Full Screen ></a></div>
![Calculation method of the maximum product after cutting](max_product_cutting_problem.assets/max_product_cutting_greedy_calculation.png){ class="animation-figure" }
<p align="center"> Figure 15-16 &nbsp; Calculation method of the maximum product after cutting </p>