第一问dp就不说了。。
然后这个网络流的建图思路就有点神奇了。。
第一问的LIS用的是传统的N^2dp做。。然后可以算出以每个数为结尾的LIS,记为dp[i],将第一问答案记做s
然后其实答案最多就是dp[i]等于s的个数,然后剩下的就是看他们能不能找到自己前面的子列了。。
首先考虑找s-1位置的数字,显然是要找dp[i]==s-1的数字,如果这个i找不到s位置的数字,那么这个数还是否有用呢?答案是没有。。可能很多人想过这个数字如果不能放在s-1的位置那可以放在更靠前的位置继续使用,然而假设真的有更靠前的位置给它放,那么我们大可以把这个数以前的序列全部替换成以他为结尾的LIS序列,然后你会发现,替换之后整个序列的长度就大于s了。。这显然不合理。。
所以可以得到一个结论,对每个数i他只能放在序列中的dp[i]位置。。
然后建图思路就十分明了了,直接将dp值差1而且可以在dp的时候转移的2个点连起来,容量为1,然后将dp值为1的和源点连边,dp值为s的和汇点连边,容量均为1。。
看起来貌似建完了,不过需要注意的是每个数字只能用一次,因此对每个点还需要拆点限制流量。。
/**
* ┏┓ ┏┓
* ┏┛┗━━━━━━━┛┗━━━┓
* ┃ ┃
* ┃ ━ ┃
* ┃ > < ┃
* ┃ ┃
* ┃... ⌒ ... ┃
* ┃ ┃
* ┗━┓ ┏━┛
* ┃ ┃ Code is far away from bug with the animal protecting
* ┃ ┃ 神兽保佑,代码无bug
* ┃ ┃
* ┃ ┃
* ┃ ┃
* ┃ ┃
* ┃ ┗━━━┓
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛
*/
#include
#include
#include
#include
#include
#include
#include
«问题描述:
给定正整数序列x1,...,xn 。
(1)计算其最长不下降子序列的长度s。
(2)计算从给定的序列中最多可取出多少个长度为s的不下降子序列。
(3)如果允许在取出的序列中多次使用x1和xn,则从给定序列中最多可取出多少个长度为s的不下降子序列。
«编程任务:
设计有效算法完成(1)(2)(3)提出的计算任务。
第1 行有1个正整数n,表示给定序列的长度。接下来的1 行有n个正整数n:x1, ..., xn。
输出格式:第1 行是最长不下降子序列的长度s。第2行是可取出的长度为s 的不下降子序列个数。第3行是允许在取出的序列中多次使用x1和xn时可取出的长度为s 的不下降子序列个数。
4 3 6 2 5
2 2 3
n≤500n\le 500n≤500