我有一个大小为 N 的正整数列表 P 。我有另一个相同大小的数字列表 C ,但 C 只能包含数字{-1,0,1}。我的目标是在i = 1..N 的情况下最大化 sum(P [i] * C [i]),但受 -k =<的限制。 sum(C [i])=< 0表示i = 1..j,所有j = 1..N ,对于某些正 k 。
示例:
If k=1, P=[1,2,3,4], then C=[-1,0,0,1] with sum -1+4 = 3
If k=2, P=[1,2,3,4], then C=[-1,-1,1,1] with sum -1-2+3+4 = 4
If k=1, P=[10, 1, 8, 6, 7], then C=[0,-1,1,-1,1] with sum = -1+8-6+7 = 8
问题是在给定任意 k 和 P 的情况下找到 C 的有效算法。
请注意将此与实际问题联系起来: P 表示生产成本或按时间间隔提供的奖励,具体取决于是否有-1(生产) C 中的0(无所事事),1(供应)。 k 是缓冲区的大小;提供的东西必须先前已经生成并填充在缓冲区中。
答案 0 :(得分:1)
有一个动态编程解决方案需要O(kN)时间:
让TextBlock
成为索引REWARD(i,n)
的最佳奖励,可以实现将1...i
个项目留在缓冲区中,如果无法处理,则n
将REWARD(i,n) = -infinity
个项留在缓冲区中的索引1...i
。
例如,n
为REWARD(1,n)
为0
,n==0
为-P[1]
,否则为n==1
。
现在,对于所有-infinity
给定REWARD(i,n)
,可以轻松计算所有n
的{{1}}。这允许我们使用自下而上的动态编程方法将REWARD(i+1,n)
n
矩阵填充到k
。
可获得的最大奖励是最高N
,因为如果REWARD(N,k)
我们总能通过提供缓冲的项目找到更好的解决方案。为了生成REWARD(N,0)
,我们会根据我们前往的操作,返回n>0
填充C
REWARD(N,0)
时所采取的步骤。