石子合并(弱化版)
题目大意
设有 堆石子排成一排,其编号为 。每堆石子有一定的质量 。
现在要将这 堆石子合并成为一堆。每次只能合并相邻的两堆,合并的代价为这两堆石子的质量之和,合并后与这两堆石子相邻的石子将和新堆相邻。合并时由于选择的顺序不同,合并的总代价也不相同。
试找出一种合理的方法,使总的代价最小,并输出最小代价。
题目分析
辨别区间 的方式:
从小区间延伸到大区间(合并等方式)。
许多括号数数题就是区间 好题,今年 不妨一做。
令 表示区间 内合并的最小代价。
枚举左右区间,再枚举中间断点来判断是否答案会变得更优:
。
其中 表示 。
枚举区间(左右+断点)复杂度为 ,中间枚举价值的部分又是 ,总时间复杂度 。
枚举价值部分可以通过前缀和优化,优化为 。
代码
//2022/1/6
const int INF=0x3f3f3f3f;
const int ma=305;
int a[ma],sum[ma];
int dp[ma][ma];
int n;
int main(void)
{
n=read();
Input_Int(n,a);
for(register int i=1;i<=n;i++)
{
sum[i]=sum[i-1]+a[i];
}
for(register int len=2;len<=n;len++)
{
for(register int l=1;l+len-1<=n;l++)
{
int r=l+len-1;
dp[l][r]=INF;
for(register int k=l;k<r;k++)
{
int w=sum[r]-sum[l-1];
dp[l][r]=min(dp[l][r],dp[l][k]+dp[k+1][r]+w);
}
}
}
printf("%d\n",dp[1][n]);
return 0;
}
本文作者:Coros_Trusds
本文链接:https://www.cnblogs.com/Coros-Trusds/p/15773115.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步