1 条题解
-
0
自动搬运
来自洛谷,原作者为

xun薰
只是一个留了几篇题解的路人搬运于
2025-08-24 21:42:22,当前版本为作者最后更新于2017-09-27 08:30:46,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
区间dp
1、 普通的搜索54分。
每一次的抉择是取当前区间的左边还是右边,搜索的边界条件是取到最后只剩下一个元素
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,ans,v[2020]; void dfs(int ste,int l,int r,int sum){ if(l==r){ ans=max(ans,sum+v[l]*ste); return; } dfs(ste+1,l+1,r,sum+ste*v[l]); dfs(ste+1,l,r-1,sum+ste*v[r]); } int main(){ scanf("%d",&n);ans=0; for(int i=1;i<=n;i++)scanf("%d",&v[i]); dfs(1,1,n,0); cout<<ans<<endl; return 0; }2、记忆化搜索 我们发现之前取的抉择可能不完全一样,但是现在面临同样的状态,那么我们就不需要搜索
多遍,开一个f[l][r]数组,表示区间[l,r]能提供的最大价值,边界条件为取完时,即数列为空时。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,ans,v[2020],f[2020][2020]; int dfs(int ste,int l,int r){ if(r<l)return 0; if(f[l][r])return f[l][r]; f[l][r]=max(dfs(ste+1,l+1,r)+ste*v[l],dfs(ste+1,l,r-1)+ste*v[r]); return f[l][r]; } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&v[i]); dfs(1,1,n); printf("%d",f[1][n]); return 0; }3、记忆化搜索中我们已经看出dp转移方程了。 第一层循环枚举区间长度,第二层循环枚举左端点。
代码:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,f[2017][2017],v[2017]; int main(){ scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&v[i]); for(int i=1;i<=n;i++)f[i][i]=v[i]*n;//一开始初始化忘记乘以n for(int i=2;i<=n;i++){ for(int l=1;l<=n;l++){ int r=l+i-1; if(r>n)break; f[l][r]=max(f[l][r-1]+v[r]*(n-i+1),f[l+1][r]+v[l]*(n-i+1)); } } printf("%d\n",f[1][n]); return 0; }这篇题解希望能帮助到区间dp入门的同学。
- 1
信息
- ID
- 1923
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 3
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者