CLRS第十五章思考题9-12

思考题15-9

首先我们在 L 表的最前和最后面分别加上 0 n ,然后将 L 表按照升序排列。记 L[i...j] L 中从下标 i j 。定义子问题 (i,j) S[L[i+1]..L[j]] 的一个最优拆分。这时候需要注意的是我们只关心 L[i+1,j1] 怎么拆分。举例来说: L=[20,17,14,11,25],n=30 ,处理过后就是 L=[0,11,14,17,20,25,30] 。子问题是 (2,6) ,即拆分 S[12...25] ,我们关心的是 L[3,5] 怎么拆。
那么现在就有点类似矩阵链乘法问题了。设子问题 (i,j) 的拆分地方为 L[k],i<k<j 。拆分后变成两个子问题:前缀 (i,k) 包括 L[i+1,k1] ,后缀 (k,j) 包括 L[k+1,j1] 。定义 cost[i,j] 是子问题 (i,j) 的最优拆分:

cost[i,j]={0mini<k<j{cost[i,k]+cost[k,j]+(L[j]L[i])}if j - i ≤1if j - i >1

BREAK-STRING(n,L)
    prepend 0 to the start of L and append n to the end of L
    m = L.length
    sort L into increasing order
    let cost[1..m,1..m] and break[1..m,1..m] be new tables
    for i = 1 to m - 1
        cost[i, i]  = cost[i, i + 1] = 0
    cost[m,m] = 0
    for len = 3 to m
        for i = 1 to m - len + 1
            j = i + len - 1
            cost[i, j]  = ∞
            for k = i + 1 to j - 1
                if cost[i, k] + cost[k, j]  < cost[i, j] 
                    cost[i, j] = cost[i, k] + cost[k, j]
                    break[i, j] = k
            cost[i, j] = cost[i, j]  + L[j] - L[i] 
    print “The minimum cost of breaking the string is ” cost[1,m]
PRINT-BREAKS(L, break, 1,m)
PRINT-BREAKS(L, break, i, j)
    if j - i2
        k = break[i, j] 
        print “Break at ” L[k]
        PRINT-BREAKS(L, break, i, k)
        PRINT-BREAKS(L, break, k, j)

总的时间复杂度是 Θ(n3)

思考题15-10

a) 很显然我们把钱投资到回报率最高的那种投资上面会得到更多的回报。

b) 令 f(k,i) 为在第 k 年我们把钱投资到第 i 个中的回报,可以得到递归式:

f(k,i)=max{f(k1,i)f1,f(k1),j)f2}+drik,ji and j[1,n]

c) 给出初始资金 d 和回报率表 r

INVESTMENT-STG(d,r):
    Let c[0..n] be an array to store the money after ith year.
    Let j[0..n] be the array that store which investment is selected in ith year.
    for i = 0 to 10:
        c[i] = 0;
        j[i] = 0;
    for k = 1 to 10:
        for i = 1 to n:
            fee = i == j[k - 1] ? f1 : f2;
            new_sum = c[k - 1] * rik - fee;
            if new_sum > c[k]:
                c[k] = new_sum;
                j[k] = i;
    return c, j;

时间复杂度 O(n)

d) 找出一个反例即可。

思考题15-11

定义子问题 (k,s) 为在第 k 个月开始时,在剩余 s 台机器的情况下满足所有第 k...n 个月的需求。设 f 为第 k 月中制造的机器数,因此第 k+1 月开始时剩余的机器数是 s+fdk 。记 cost[k,s] 是子问题 (k,s) 的一个最优计划,第 k 月中制造的机器数 f 的上下界分别是:
1) 在上月剩下 s 台机器时,最少生产 max(dks,0) 台。记下界 L(k,s)=max(dks,0)
2) 在上月剩下 s 台机器时,最多生产上界 U(k,s)=(i=kndi)s
最后一个月只需生产满足 L[n,s] 的台数即可。其他月生产的机器是弹性的,满足最优解就行。

cost[k,s]=cmax(L(n,s)m,0)+h(s+L(n,s)dn)minL(k,s)kU(k,s){cost[k+1,s+fdk]+cmax(fm,0)+h(s+fdk)}if k=nif 0<k<n

INVENTORY-PLANNING(n,m, c,D, d, h)
    let cost[1..n,0..D] and make[1..n,0..D] be new tables
    // Compute cost[n, 0..D] and make[n, 0..D].
    for s = 0 to D
        f = max(dn - s, 0)
        cost[n, s] = c·max(f - m, 0) + h(s + f - dn)
        make[n, s] = f
    // Compute cost[1..n-1,0..D] and make[1..n - 1,0..D].
    U = dn
    for k = n - 1 downto 1
        U = U + dk
        for s = 0 to D
            cost[k, s] = ∞ 
            for f = max(dk - s, 0) to U - s
                val = cost[k + 1, s + f - dk] +  c·max(f - m, 0) + h(s + f - dk)
                if val < cost[k, s]
                    cost[k, s] = val
                    make[k, s] = f
    print cost[1,0]
    PRINT-PLAN(make, n, d)

PRINT-PLAN(make, n, d)
    s = 0
    for k = 1 to n
        print “For month ” k “ manufacture ” make[k, s] “ machines”
        s = s + make[k, s] - dk

INVENTORY-PLANNING的时空复杂度分别是 O(nD2),O(nD)

思考题15-12

设球员 p 的签约费用和 VORP 分别是 p.cost,p.vorp,同时认为签约费用是以 10 万美元为单位。
由于先签约哪个位置的球员没有影响,我们假设从第一个位置签约到最后一个位置。对每个位置,要么签约一个队员,要么使用现有球员。假设签约位置 1 的球员 p ,我们剩下 Xp 的钱签约其他位置的球员。
定义一个球员签约费用和 VORP 的集合,集合中所有球员签约费用和 VORP 的总和就是要求的。记 (i,x) 为子问题:考虑位置为 i,i+1,...,N 并且总的费用 x 美元,什么样的集合使得 VORP 最大?一个有效的集合 (i,x) 是集合中球员都在 i,i+1,...,N 位置,每个球员打一个位置,每个位置至多一个球员,总的费用最多 x 美元。球员最优集合是最大的 VORP 的有效集合 (i,x)。子问题具有最优子结构的证明略。
i<N 时检查两个子问题并选择最优的一个,设 v[i,x] (i,x) 中的最大 VORP。 S(i,x) 为打位置 i 且签约费用至多为 x 的球员集合,得到下列递归表达式,其中空集合返回

v[i,x]=maxpS(N,x){p.vorp}max{v[i+1,x],maxpS(i,x){p.vorp+v[i+1,xp.vorp]}}if i=Nif i<N

pij 表示在第 i 位置的第 j 个球员。

FREE-AGENT-VORP(p,N,P,X)
    let v[1..N][O..X] and who[1..N][0..X] be new tables
    for x = 0 to X
        v[N, x] = −∞
        who[N, x] = 0
        for k = 1 to P
            if p_Nk.cost ≤ x and p_Nk.vorp > v[N,x]
                v[N,x] = p_Nk.vorp
                who[N,x] = k
    for i = N - 1 downto 1
        for x = 0 to X
            v[i, x] = v[i + 1, x]
            who[i, x] = 0
            for k = 1 to P
                if p_ik.cost ≤ x and v[i + 1, x - p_ik.cost] + p_ik.orp > v[i, x]
                    v[i, x] = v[i + 1, x - p_ik.cost] + p_ik.vorp
                    who[i, x] = k
    print “The maximum value of VORP is ” v[1,X]
    amt = X
    for i = 1 to N
        k = who[i, amt]
        if k ≠ 0
            print “sign player ” p_ik
            amt = amt - p_ik.cost
    print “The total money spent is ” X - amt

时间和空间复杂度分别是 Θ(NPX),Θ(NX)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值