Algorithm spoj混合物:需要逻辑方面的帮助吗

Algorithm spoj混合物:需要逻辑方面的帮助吗,algorithm,dynamic-programming,Algorithm,Dynamic Programming,问题要求尽量减少产生的烟雾 我的做法: 因为在任何时刻,只会拾取相邻的混合物。所以我试着用dp。就像我知道n-1混合物的答案一样,我可以得到n混合物的答案 怎么做 第n种混合物为 情况1:与第(n-1)种混合物混合,其结果与第1种n-2种混合物的合成混合物混合。或 案例2:将其与n-1混合物的合成混合物混合 设dp[i]表示前i种混合物的最小烟度,res[i]表示前i种混合物的合成混合物。当然,它们将包含优化的值。A[i]表示第i种混合物的颜色 所以 对于案例1:dp[i]=dp[i-2]+A[

问题要求尽量减少产生的烟雾

我的做法: 因为在任何时刻,只会拾取相邻的混合物。所以我试着用dp。就像我知道n-1混合物的答案一样,我可以得到n混合物的答案

怎么做 第n种混合物为

情况1:与第(n-1)种混合物混合,其结果与第1种n-2种混合物的合成混合物混合。或

案例2:将其与n-1混合物的合成混合物混合

设dp[i]表示前i种混合物的最小烟度,res[i]表示前i种混合物的合成混合物。当然,它们将包含优化的值。A[i]表示第i种混合物的颜色

所以

对于案例1:dp[i]=dp[i-2]+A[i-1]A[i]+res[i-2](A[i-1]+A[i])%100; res[i]=(res[i-2]+A[i]+A[i-1])%100

对于案例2:dp[i]=dp[i-1]+res[i-1]*A[i]; res[i]=(res[i-1]+A[i])%100

基本情况:

若只有1种混合物给出烟=0,则生成的混合物为混合物本身。 如果只有两种混合物给出烟=A[0]*A[1]和再过滤=(A[0]+A[1])%100

我的代码:在4个案例中,它只通过了1个(不是示例测试案例) 我的逻辑哪里错了

问题陈述 哈利·波特面前有n个混合物,排成一排。每个混合物有100种不同颜色中的一种(颜色的数字从0到99)

他想把这些混合物混合在一起。在每一步中,他将取两种相邻的混合物,将它们混合在一起,然后将得到的混合物放在适当的位置

当混合两种颜色a和b的混合物时,所得混合物的颜色(a+b)为mod 100

而且,在这个过程中会有一些烟雾。混合两种颜色a和b的混合物时产生的烟雾量为a*b

找出当哈利把所有的混合物混合在一起时,他能得到的最小烟雾量是多少

输入 输入中将有许多测试用例

每个测试用例的第一行将包含n,混合物的数量,1 n//混合料数量 int A[n]; for(int i=0;i>A[i];//填充它们的值。 if(n==1)//基本情况 {
cout您的代码为输入输出6500,但正确的结果是3500:

20  10  30  30  40
200/30  900/60
  30      60    40
          2400/0
  30      0

smoke = 200 + 900 + 2400 = 3500
一个诀窍是认识到(或学习)任何折叠间隔的最终颜色都是相同的,无论其混合顺序如何。下面的Python代码使用了分治,被接受

我们可以使用两种想法:(1)由于加法的关联性,我们选择的任何特定间隔通过混合一路折叠到一个元素,无论混合顺序如何,都将产生相同的颜色;(2)为任何间隔(特别是完整列表)提供最佳混合顺序,因为混合是在相邻颜色之间进行的,所以该间隔的最后一次混合必须有一个最佳的单一位置,换句话说,一个将整个间隔分成两部分的单一最佳位置,以便在最终混合之前,每一侧都完全折叠

考虑到这两种想法,我们基本上建立了一种“暴力”循环——尝试每一种可能的分割,知道每个部分的颜色不是一个我们需要不止一种可能性的维度,并在这两个部分上执行相同的循环。希望代码中的基本情况非常清楚

import sys

# Returns (smoke, colour)
def f(lst, i, j, memo):
  # Empty interval
  if i > j:
    return (float('inf'), 0)

  # Single element
  if i == j:
    return (0, lst[i])

  if (i, j) in memo:
    return memo[(i, j)]

  best = (float('inf'), -1)

  for k in xrange(i, j):
    smoke_l, colour_l = f(lst, i, k, memo)
    smoke_r, colour_r = f(lst, k + 1, j, memo)
    smoke = smoke_l + smoke_r + colour_l * colour_r
    colour = (colour_l + colour_r) % 100
    best = min(best, (smoke, colour))

  memo[(i, j)] = best
  return best


# I/O
while True:
  line = sys.stdin.readline()
  if line:
    n = int(line)
    if n == 0:
      continue
    lst = sys.stdin.readline()
    lst = map(int, lst.split())
    print f(lst, 0, n-1, {})[0]
  else:
    break

您的代码输出6500作为输入
20 10 30 40
,但正确的结果是3500:

20  10  30  30  40
200/30  900/60
  30      60    40
          2400/0
  30      0

smoke = 200 + 900 + 2400 = 3500
一个诀窍是认识到(或学习)任何折叠间隔的最终颜色都是相同的,无论其混合顺序如何。下面的Python代码使用了分治,被接受

我们可以使用两种想法:(1)由于加法的关联性,我们选择的任何特定间隔通过混合一路折叠到一个元素,无论混合顺序如何,都将产生相同的颜色;(2)为任何间隔(特别是完整列表)提供最佳混合顺序,因为混合是在相邻颜色之间进行的,所以该间隔的最后一次混合必须有一个最佳的单一位置,换句话说,一个将整个间隔分成两部分的单一最佳位置,以便在最终混合之前,每一侧都完全折叠

考虑到这两种想法,我们基本上建立了一种“暴力”循环——尝试每一种可能的分割,知道每个部分的颜色不是一个我们需要不止一种可能性的维度,并在这两个部分上执行相同的循环。希望代码中的基本情况非常清楚

import sys

# Returns (smoke, colour)
def f(lst, i, j, memo):
  # Empty interval
  if i > j:
    return (float('inf'), 0)

  # Single element
  if i == j:
    return (0, lst[i])

  if (i, j) in memo:
    return memo[(i, j)]

  best = (float('inf'), -1)

  for k in xrange(i, j):
    smoke_l, colour_l = f(lst, i, k, memo)
    smoke_r, colour_r = f(lst, k + 1, j, memo)
    smoke = smoke_l + smoke_r + colour_l * colour_r
    colour = (colour_l + colour_r) % 100
    best = min(best, (smoke, colour))

  memo[(i, j)] = best
  return best


# I/O
while True:
  line = sys.stdin.readline()
  if line:
    n = int(line)
    if n == 0:
      continue
    lst = sys.stdin.readline()
    lst = map(int, lst.split())
    print f(lst, 0, n-1, {})[0]
  else:
    break

你能详细解释一下方法吗?@chaitanya_12789当然,我在答案中添加了更多信息。你能详细解释一下方法吗?@chaitanya_12789当然,我在答案中添加了更多信息。
import sys

# Returns (smoke, colour)
def f(lst, i, j, memo):
  # Empty interval
  if i > j:
    return (float('inf'), 0)

  # Single element
  if i == j:
    return (0, lst[i])

  if (i, j) in memo:
    return memo[(i, j)]

  best = (float('inf'), -1)

  for k in xrange(i, j):
    smoke_l, colour_l = f(lst, i, k, memo)
    smoke_r, colour_r = f(lst, k + 1, j, memo)
    smoke = smoke_l + smoke_r + colour_l * colour_r
    colour = (colour_l + colour_r) % 100
    best = min(best, (smoke, colour))

  memo[(i, j)] = best
  return best


# I/O
while True:
  line = sys.stdin.readline()
  if line:
    n = int(line)
    if n == 0:
      continue
    lst = sys.stdin.readline()
    lst = map(int, lst.split())
    print f(lst, 0, n-1, {})[0]
  else:
    break