mirror of
https://github.com/krahets/hello-algo.git
synced 2026-04-29 13:00:56 +08:00
build
This commit is contained in:
@@ -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)$**.
|
||||
|
||||
@@ -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 Advantages and limitations of greedy algorithms
|
||||
|
||||
@@ -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. Proof of correctness
|
||||
|
||||
The reason why the greedy method is faster than enumeration is that each round of greedy selection "skips" some states.
|
||||
|
||||
@@ -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>
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> Figure 15-16 Calculation method of the maximum product after cutting </p>
|
||||
|
||||
Reference in New Issue
Block a user