codeforces 704B

13 篇文章 0 订阅
1 篇文章 0 订阅

luogu链接

解法

高妙的dp:
首先调整一下权值:
a i = a i + x i , b i = b i − x i , c i = c i + x i , d i = d i − x i a_i=a_i+x_i,b_i=b_i-x_i,c_i=c_i+x_i,d_i=d_i-x_i ai=ai+xi,bi=bixi,ci=ci+xi,di=dixi
这样就可以:
f ( i , j ) = d i + a j        ( i < j ) f(i,j)=d_i+a_j~~~~~~(i<j) f(i,j)=di+aj      (i<j)
f ( i , j ) = c i + b j        ( i > j ) f(i,j)=c_i+b_j~~~~~~(i>j) f(i,j)=ci+bj      (i>j)
然后似乎是一种套路dp模式:记 d p [ i ] [ j ] dp[i][j] dp[i][j]表示前i-1个点,形成了j条链的最小权值和,枚举一下第i个点的连边方式(好像和插头dp有点类似)进行转移。
最后答案是 d p [ n + 1 ] [ 1 ] dp[n+1][1] dp[n+1][1]
首先考虑 ( i ! = s ) 且 ( i ! = e ) (i!=s)且(i!=e) (i!=s)(i!=e)的情况:
首先s和e所在的链会在最后合并,所以 j ≥ ( i > e ) + ( i > s ) j\ge (i>e)+(i>s) j(i>e)+(i>s),表示至少有哪些链,然后枚举i的两个插头的方向:
如果向i连边的点比i小,那么i贡献一个 a i a_i ai,否则贡献一个 b i b_i bi,然后i连出去的点比i小,i贡献一个 c i c_i ci,否则贡献一个 d i d_i di,然后再这些连边过程中,可能会出现改变链总数的情况:当i贡献 a i a_i ai c i c_i ci的时候,说明原先两条没有关系的链被连到了一起。链的总数-1.
当i贡献 b i b_i bi d i d_i di的时候,说明这个点所在的链和之前i-1个点没有关系。需要新加一条链。
然后剩下的两种情况要注意,它们能否出现要通过讨论p的数量和i,s,e的位置关系。
考虑 i = = s i==s i==s的情况:
这个时候只能从i向其它点连边,其它的分类讨论和上面一样
i = = e i==e i==e的情况
这时候只能从其他点连回i。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值