题目大意:一个圆圈中有很多n个点(包括起点),其中除了起点外其他点除都有需要送的包裹。现在已经迟到了,而每到一个点处送了包裹都要因为迟到而每迟到1min扣和包裹数相同的钱。给定n和每个点的包裹数还有前一个点到下一个点的时间(来回一样),求最少需要赔的钱。
一类折线问题的DP --- 以某个点位中心,不断扩展两边折返,形成区间更新
clock_time[i]0到i点时间。顺时针
anti_clock_time[i]i到0点时间。逆时针
w[i][j]i到j有的包裹总数。
l[i][j]表示站在i处要处理i到j最少需要赔的钱
r[i][j]表示站在j处要处理i到j最少需要赔的钱
现在来分析l[i][j](r[i][j]同理),即站在i处要处理i到j最少需要赔的钱,那么可以有两种情况:①先走到i+1,此时就变成了l[i+1][j],又因为先走了time[i]的时间(从i到i+1),所以i+1到j的处理时间都要推迟time[i],所以l[i][j] = min(l[i][j], l[i+1][j] + time[i]*w[i+1][j]);②先从外侧走到j,然后就是r[i+1][j],而此时先花掉的时间就是clock_time[i] + anti_clock_time[j](#),所以l[i][j] = min(l[i][j], r[i+1][j] + (#)*w[i+1][j])。
而最终的状态就是l\r[0][n-1] or l\r[1][0],但因为[1][0]表示不方便,所以我们在0..n-1的基础上增加一个n来表示0,这样l\r[1][0]就能表示成l\r[1][n],然后再综合一下,结果就是min(l[0][n], r[0][n])~~~(代码中因为n自增了1,所以那儿是[0][n-1])
代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include