关于一类动态规划题的总结

来源:互联网 发布:c语言网络爬虫 编辑:程序博客网 时间:2024/06/10 08:42

关于一类DP题目的总结

1

题面:N个数字(有正有负)排成一排,选出连续一段使得和最大N <= 1000000

S[i]表示前i个数的和

Ans = max{ S[i] –S[j] }, i>j>=0

Ans = max{ S[i] –min{S[j]} }, i>j>=0

边扫描边记录一个min值

时间复杂度O(N)

 

2

题面:N个数字(有正有负)排成一排,选出不重叠的连续两段使得和最大N <= 1000000


正向扫描一遍,求出

F(x)=Max{ S[i] - S[j]}, x >= i > j >= 0

反向扫描一遍

G(x)=Max{ S[i] - S[j]}, i > j > x

枚举分割点

Ans=Max{ F(x) + G(x)}, 1 <= x <= N

时间复杂度O(N)

 

3

题面:N个数字(有正有负)排成一环,选出连续一段使得和最大N <= 1000000

裸搞的话是O(N2)的吧,尽管我觉得裸搞都难想些

任取一处断环成链(并非复制数组)

若不跨越断点,按照1的方法做

若跨越断点,则未取部分对应最小和,按1求解

时间复杂度O(N)

 

4.

题面:N个数字(有正有负)排成一排,选出长度不超过L的连续一段使得和最大N <= 1000000

S[i]表示前i个数的和

Ans = max{ S[i] – S[j]}, i – j <= L

       = max{ S[i] – min{S[j]} }, i – j <= L

用堆或双端队列(单调队列)完成取每连续L个数中得最小值的操作

若j2<j1且S[j1]>S[j2]则j不可能最优

用队列维护

    (j1<j2<j3……)   (S[j1]<S[j2]<S[j3]……)

需要操作

----删除队首元素

----删除队尾不可能最优的元素

----队尾加入元素

时间复杂度O(N)

再回顾3如果我们将数组复制,再用此题单调队列方法维护亦可

 

5

题面:N个数字(正)排成一排,选出不重叠的长度不超过L的K段使得和最大N, M, L <= 1000

F[i][j]表示第j段最后一个为第i个数字时的最大和

F[i][j] = Max{ f[i- L][j - 1]+s[i]-s[i - L],f[i - 1][j] }

还有一种类似的状态设计,不讲

时间复杂度O(N2)

 

6

题面:N个数字(正)排成一排,选出连续的长度不超过L的某些段(每段不得相邻)使得和最大N <= 1000000,L <= 100000

单调队列

时间复杂度O(N)

 

7

题面:N个数字(有正有负)排成一环,选出不重叠的连续的K段使得和最大N <= 100000, K <= 10

如3方法断环成链

F[i][j]表示前i个数取了j段的最大和

F[i][j] = Max{ F[k][j-1]+ S[i] - S[k] }, F[i-1][j] , k<i

     = Max{Max{ F[k][j-1] - S[k] } + S[i], F[i-1][j] }, k<i

优化:G[i][j]=Max{ F[k][j-1] - S[k] }, k<i

时间复杂度O(N2)


8

题面:N个数字(有正有负)排成一排,选出连续一段使得和最大,且求方案数N <= 1000000

此题是1的拓展

建立在理解1的基础上

1.在往后扫描时,若最大字段和一定时,cnt+1

2.在往后扫描时,若有同样的s[j]去更新min值,cmin+1

3.在往后扫描时,若最大字段和改变,cnt=1,cmin=1

最终方案数则为 cnt + cmin!


从学长资料里蒯了一些

也加上了最近KS的两道题

希望能对读者有所帮助

一有类似知识我将更新上来

原创粉丝点击