1 # 4 4 3
2 # [
3 # [[-1, -1, -1], [-1, -1, -1], [-1, -1, -1], [-1, -1, -1], [-1, -1, -1]],
4 # [[-1, -1, -1], [1, -1, -1], [2, -1, -1], [3, -1, -1], [4, 2, -1]],
5 # [[-1, -1, -1], [2, -1, -1], [4, -1, -1], [6, -1, -1], [8, 4, -1]],
6 # [[-1, -1, -1], [3, -1, -1], [6, -1, -1], [9, -1, -1], [12, 6, -1]],
7 # [[-1, -1, -1], [4, 2, -1], [8, 4, -1], [12, 6, -1], [-1, -1, 6]]
8 # ]
9 # DFS(4,4,2) = max(DFS(3,4,1),DFS(1,4,0))
10 # 6 = max(6,4)
11
12 # minBigestArea三维列表,0:宽,1:高,2:共切几刀,在w,h的长方形切m刀最大蛋糕的面积最小值
13 minBiggestArea = []
14 INF = float("inf")
15
16
17 # 竖着切
18 def SV(w, h, k):
19 sv = INF
20 # 第一刀竖着切,因为是整数,刀的位置在1——w之间,遍历第一刀切的位置
21 for i in range(1, w):
22 # 第一刀切下去了,那么就会产生左右两块蛋糕,剩下切的刀数就是0——k-1,所以遍历循环的范围是k
23 # 第一刀切下去后,产生2块蛋糕,那么对左边的蛋糕可能切几刀,取值从0——k-1
24 # 知道左边切下去的刀数了,那么就可以计算出还剩余的刀数就给右边来切
25 # 以4 4 3为例,如果第一刀切的位置为3,那么就会产生2块蛋糕,左边w=3,h=4 ,右边w=1,h=4
26 # 竖切的情况:
27 # DFS(4,4,2) = max(DFS(3,4,0),DFS(1,4,1))或者max(DFS(3,4,1),DFS(1,4,0))
28 # 因为我们需要找最大那块蛋糕的值,因此要取左右2块蛋糕的max值
29 # 那么不同的切法,最大那块蛋糕的值有许多种,题目要求最小的,所以最后就有个min
30 for kk in range(0, k):
31 # 求1切下去后左边蛋糕在i,h,kk的情况下最大蛋糕的最小值
32 leftValue = DFS(i, h, kk)
33 # 求1切下去后右边边蛋糕在w-i,h,k-1-kk的情况下最大蛋糕的最小值
34 rightValue = DFS(w-i, h, k-1-kk)
35 # 左右蛋糕最大蛋糕的最小值求出了,合起来比较,那么sv在w、h、k下最大蛋糕的最小值即可算出
36 sv = min(sv, max(leftValue, rightValue))
37 return sv
38
39
40 # 横着切与竖的原理是一样的,唯一区别这里是w不变,h变了
41 def SH(w, h, k):
42 sh = INF
43 for i in range(1, h):
44 for kk in range(0, k):
45 leftValue = DFS(w, i, kk)
46 rightValue = DFS(w, h-i, k-1-kk)
47 sh = min(sh, max(leftValue, rightValue))
48 return sh
49
50
51 # w-宽度 h-高度 k-共切几刀
52 def DFS(w, h, k):
53 global minBiggestArea
54 # 如果该位置的最大蛋糕最小值已经计算好了,不需要重复计算,直接读出
55 if minBiggestArea[w][h][k] != -1:
56 return minBiggestArea[w][h][k]
57 # w=4,h=4,因为要求蛋糕的边是整数,因此最多可以产生16块小蛋糕,也就是最多可以切15刀
58 # 如果切16刀,蛋糕分不出17块,完成不了,因此返回无穷大
59 if w * h < k + 1:
60 minBiggestArea[w][h][k] = INF
61 return minBiggestArea[w][h][k]
62 # 如果一刀都不切,那么w*h就是最大蛋糕的最小值
63 if k == 0:
64 minBiggestArea[w][h][k] = w * h
65 return minBiggestArea[w][h][k]
66 # 因为蛋糕第一刀切下去,有竖、横两个方向,所以要分别求
67 # 第一刀竖着切最大蛋糕的最小值,横着切所得最大蛋糕的最小值
68 # 然后再对这2个取最小值,即得该大小蛋糕,共切几刀的最大蛋糕最小值
69 minBiggestArea[w][h][k] = min(SV(w, h, k), SH(w, h, k))
70 return minBiggestArea[w][h][k]
71
72
73 def main():
74 global minBiggestArea
75 while True:
76 w, h, m = map(int, input().split())
77 if w == 0 and h == 0 and m == 0:
78 break
79 # 构建1个三维列表,因为列表的序号从0开始计算,为了计算方便w、h多增加1,
80 # 列表中w、h位置0的值没有意义,不存储数据,仅为计算方便
81 # 三维列表从1开始存储,初始化为-1,如果计算过,就存储值下来,避免重复计算,提高效率
82 # m这个位置存储的是刀数,要分成m块,需要m-1刀,比如m=3,只需要2刀,所以只需要生成0、1、2
83 # 因此m的位置不需要增加1
84 minBiggestArea = [[[-1 for i in range(m)] for i in range(h+1)] for i in range(w+1)]
85 # print(minBigestArea)
86 # w-宽度、h-高度,函数的第3个参数表示总共刀数,切m-1刀,即可得到m块蛋糕
87 optimalValue = DFS(w, h, m-1)
88 print("最大蛋糕块的面积下限为:%d" % optimalValue)
89
90 return 0
91
92
93 if __name__ == '__main__':
94 main()