区间dp学习笔记
Posted Wrasar
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了区间dp学习笔记相关的知识,希望对你有一定的参考价值。
退役人回来了/fad
回来学习dp(
于是先好好学习一下区间dp吧qwq
一.什么是区间dp
大家都知道什么是dp吧,dp有三部曲:定义状态,状态转移方程,边界条件。
那区间dp呢?差不多,只是它有一个范围限制,就是说它的操作只可以在这个范围内进行。
所以我们区间dp的循环有三个维度:区间长度,左端点(有了左端点和区间长度右端点就出来了对不对),断点。它们分别对应这区间dp的三个主体:阶段。状态,决策点。
干巴巴的东西说多了没用,我们直接看例题!
区间dp模板详解
找了一道模板:ybt1274.合并石子
就是纯模板题,要注意的就是合并操作的dp数组需要做初始化,因为是求最小值。
直接上核心代码qwq?
注意:要加上的得分就是两堆石子的数量总和,建议前缀和预处理这种区间和问题。
memset(dp,0x3f,sizeof(dp));
for(int i=0;i<=n;i++)dp[i][i]=0;
for(int len=2;len<=n;len++){//因为预处理过了区间长度为1的情况,所以len要从2开始qaq
for(int i=1;i+len-1<=n;i++){
int j=i+len-1;
for(int k=i;k<=j-1;k++){
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+s[j]-s[i-1]);
}
}
}
既然说到有区间限制,我们就顺便说说没用区间限制的时候。
那就是这个P1090.合并果子。
于是可以想到用贪心结合栈解决了qeq
以下是核心代码:
while(pq.size()>1){
x=pq.top();
pq.pop();
y=pq.top();
pq.pop();
ans+=(x+y);
pq.push(x+y);
}
三.解题报告
这个绝对会更新(
先来一个板子题的强化版。
和板子题不太一样的点有两个:这是一个环;要求最大和最小同时维护。
第二个简单,第一个有难度。
于是我们来拆环为链!
因为对于这个环,我们随便选一个点把它拆开,就有 \\(n\\) 种方式。
而我们把题目中给的排列方式double一下,这个链就包含了所有拆分方式!
于是就很简单了~~
核心代码:
for(int i=1;i<=n;i++){
cin>>a[i];
a[n+i]=a[i];
}
n*=2;
memset(minn,0x3f,sizeof(minn));
minn[0][0]=maxn[0][0]=0;
for(int i=1;i<=n;i++){
s[i]=s[i-1]+a[i];
minn[i][i]=maxn[i][i]=0;
}
for(int len=2;len<=n;len++){
for(int i=1;i+len-1<=n;i++){
int j=i+len-1;
for(int k=i;k<=j-1;k++){
minn[i][j]=min(minn[i][j],minn[i][k]+minn[k+1][j]+s[j]-s[i-1]);
maxn[i][j]=max(maxn[i][j],maxn[i][k]+maxn[k+1][j]+s[j]-s[i-1]);
}
}
}
输出操作被和谐掉了(
建议自行思考输出什么qeq
绿就绿在这个环了,而环的操作已经讲了,直接和谐掉代码(bushi
非常好,这是一道和模板题基本上没有差别的题(
代码被lk鸽鸽吃掉了。
5.P2858 [USACO06FEB]Treats for the Cows G/S
这个非常重要,lk鸽鸽明天再写(“钛晚了”
求监督lk鸽鸽不要咕咕咕
「学习笔记」区间 DP
以上是关于区间dp学习笔记的主要内容,如果未能解决你的问题,请参考以下文章