【线段数+DP】HDU 3698 Let the light guide us

通道:http://acm.hdu.edu.cn/showproblem.php?pid=3698

题意:每行选1个数,使得最后选的数的和最小,上下两行所选的数满足:|j-k|≤f(i,j)+f(i+1,k).

思路:dp[i][j]:前i行选了j的最小,转移dp[i+1][k] =min(dp[i][j]{满足|j-k|≤f(i,j)+f(i+1,k).})+cost[i+1][k],复杂度n*m*m,优化方案是对于min(dp[i][j]{满足|j-k|≤f(i,j)+f(i+1,k).}),用线段数维护即可,{将|j-k|≤f(i,j)+f(i+1,k)去绝对值后变成:k-f[i+1][k] <= j + f[i][j] 或 j-f[i][j]<= k + f[i+1][k]},对于i行维护|min(dp[i][j]{满足|j-k|≤f(i,j)+f(i+1,k).},假设我们知道了区间[ k - f ( i + 1 , k ) , k + f ( i + 1 , k ) ]内的最小的dp[ i ][ j ],那么就可以得到dp[ i + 1][ k ]了,用线段树的区间更新插入第 i 行每个 dp[ i ][ j ] 可以影响的区间[ j - f ( i , j ) , j + f ( i , j ) ],然后每个点只取能覆盖到这个点的最小的dp[ i ][ j ]即可。

代码:https://github.com/Mithril0rd/Rojo/blob/master/hdu3698.cpp

TAG:线段数+DP

posted @ 2014-11-11 13:23  mithrilhan  阅读(265)  评论(0编辑  收藏  举报