description
每次可以选择连续一段,删掉,两边合并过来。删一段的代价为
solution
这种带区间拼接合并,而且很小的的,容易想到区间dp
表示使中最小值为,最大值为的最小代价。
思路1
通常决策考虑第一个或最后一个的选取情况。我喜欢考虑最后一个()
- 留下
- 删
枚举划分点,右边删,左边留。
我们发现不需要考虑max,min只需代价最小。因此令表示删完的最小代价。
思路1 code
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=55;
int w[N],g[N][N],f[N][N][N][N],val[N];
int main() {
int n,a,b;scanf("%d%d%d",&n,&a,&b);
for(int i=1;i<=n;i++)scanf("%d",&w[i]),val[i]=w[i];
sort(val+1,val+1+n);
int m=unique(val+1,val+1+n)-val;
for(int i=1;i<=n;i++)w[i]=lower_bound(val+1,val+m,w[i])-val;
memset(f,0x3f,sizeof(f));
memset(g,0x3f,sizeof(g));
for(int i=1;i<=n;i++)g[i][i]=a,f[i][i][w[i]][w[i]]=0;
for(int l=n;l;l--) {
for(int r=l+1;r<=n;r++) {
for(int x=1;x<m;x++) {
for(int y=1;y<m;y++) {
f[l][r][min(x,w[r])][max(y,w[r])]=min(f[l][r][min(x,w[r])][max(y,w[r])],f[l][r-1][x][y]);
for(int k=l;k<r;k++) {f[l][r][x][y]=min(f[l][r][x][y],f[l][k][x][y]+g[k+1][r]);}
}
}
for(int x=1;x<m;x++)for(int y=1;y<m;y++)g[l][r]=min(g[l][r],f[l][r][x][y]+a+b*(val[y]-val[x])*(val[y]-val[x]));
}
}
printf("%d",g[1][n]);
return 0;
}
思路2
还是一样的要定义。
这个要直率的多,直接考虑所有情况。
- 删左半边
- 删右半边
- 两边都不删,因此两个的3,4维都分别要是
略
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人