QBXT 2018春季DP&图论班 2018.5.3 --- 区间DP专题
Posted loi-brilliant
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QBXT 2018春季DP&图论班 2018.5.3 --- 区间DP专题相关的知识,希望对你有一定的参考价值。
本文题目等来自北京大学张浩威学长的PPT。
1.区间DP:解决有关两个或以上的区间的合并或删除的问题(最大/小次数/价值、方案总数、可行性等)。
2.石子合并:
有n堆石子排成一排,第i堆石子的个数为ai。
每次可以将相邻两堆合并成一堆。
合并的代价为两堆石子的石子个数之和。
设计方案要求代价之和最小。
状态:dp[l][r]表示只考虑区间l~r的石子,将它们合并的最小代价。
状态转移:dp[l][r]=min{dp[l][r],dp[l][k]+dp[k+1][r]+s[r]-s[l-1]}
l~r这一堆石子可以分为l~k和k+1~r两堆石子,只考虑两堆石子时各自最小代价和加上将这两堆石子合并的代价和,这个可以用前缀和优化。
边界:dp[i][i]=0 只有一堆石子时不用合并,代价为0。
代码实现:
for(int len=1;len<n;len++)//枚举区间长度,注意取值范围 for(int l=1;l<=n-len;l++) //枚举左端点 { int r=l+len;//右端点 dp[l][r]=INF; for(int k=l;k<r;k++) { dp[l][r]=min(dp[l][r],dp[l][k]+dp[k+1][r]+s[r]-s[l-1]); } }
还有一种倒序枚举左端点,正序枚举右端点的做法,也能够保证状态转移合法,但不太直观。
石子合并 这道题可以用四边形不等式优化,然而据说很难理解 ,此处呈上zhw的代码,证明略。
for (len=1; len<n; len++) len左端点和右端点的差值 for (l=1; l<=n-len; l++) { r=l+len; dp[l][r]=INF; for (k=f[l][r-1]; k<=f[l+1][r]; k++) if (dp[l][k]+dp[k+1][r]+s[r]-s[l-1]<dp[l][r]) { dp[l][r]=dp[l][k]+dp[k+1][r]+s[r]-s[l-1]; f[l][r]=k; } }
3.石子合并+
有n堆石子排成一排,第i堆石子的个数为ai。
每次可以将相邻2~3堆合并成一堆。
合并的代价为这2/3堆石子的石子个数之和。
设计方案要求代价之和最小。
同上题,枚举两个断点,该一下转移方程,再for一for就A了。
for (l=1; l<=n; l++) dp[l][l]=0; for (len=1; len<n; len++) len左端点和右端点的差值 for (l=1; l<=n-len; l++) { r=l+len; dp[l][r]=INF; for (k=l; k<r; k++) dp[l][r]=min(dp[l][r],dp[l][k]+dp[k+1][r]+s[r]-s[l-1]); for (k=l; k<r; k++) for (t=k+1; t<r; t++) dp[l][r]=min(dp[l][r],dp[l][k]+dp[k+1][t]+dp[t+1][r]+s[r]-s[l-1]); }
4.石子合并++(?)
有n堆石子排成一排,第i堆石子的个数为ai。
每次可以将相邻2~n堆合并成一堆。
合并的代价为这2/3/.../n堆石子的石子个数之和。
设计方案要求代价之和最小。
思维题。。。直接一次性把n堆合成一堆即可。
5.加分二叉树
6.hihocoder1110 正则表达式
给定一个字符串,判断其是否为合法的正则表达式。
一个正则表达式定义为:
1:0是正则表达式,1也是正则表达式。
2:P和Q都是正则表达式,则PQ是正则表达式。
3:P是正则表达式,则(P)是正则表达式
4:P是正则表达式,则P*也是正则表达式
5:P和Q都是正则表达式,则P|Q是正则表达式。
010101101*
(11|0*)* 都是正则表达式。
|S|<=100。
区间DP判断正则表达式是否合法。
对于1:枚举字符串每一个字符,if(s[i]==‘0‘||s[i]==‘1‘) dp[i][i]=1;else dp[i][i]=0;
2:枚举断点,if(dp[i][k]&&dp[k+1][r]) dp[l][r]=1;
3:if(s[l]==‘(’&&s[r]==‘)‘&&dp[l+1][r-1]) dp[l][r]=1;
4:if(s[r]==‘*‘&&dp[l][r-1]) dp[l][r]=1;
5:枚举‘|‘的位置 if(s[k]==‘|‘&&dp[l][k]&&dp[k+1][r]) dp[l][r]=1;
最终if(dp[1][n]) cout<<yes ;else cout<<no;
7.D--游戏
给定n个数,每次可以删除其中连续若干个数字,要求其数字个数为2个且为等差数列,等差数列的差值k∈A,集合A给定。
求这n个数字是否能被删除。
n<=500。
8.D-游戏
9.D游戏
10.D+游戏
11.HDU 5693 D++游戏
12.HDU 5181 numbers
以上是关于QBXT 2018春季DP&图论班 2018.5.3 --- 区间DP专题的主要内容,如果未能解决你的问题,请参考以下文章