Algorithm spoj混合物:需要逻辑方面的帮助吗
问题要求尽量减少产生的烟雾 我的做法: 因为在任何时刻,只会拾取相邻的混合物。所以我试着用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)//基本情况 {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[
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