AT_dp_n Slimes题解
题目描述
有 N 只史莱姆排成一行。最初,从左到右第 i 只史莱姆的大小为 ai。
太郎君想要将所有史莱姆合成为一只。他会不断重复以下操作,直到只剩下一只史莱姆:
- 选择左右相邻的两只史莱姆,将它们合成为一只新的史莱姆。合成前两只史莱姆的大小分别为 x 和 y,合成后的史莱姆大小为 x+y。此时,太郎君需要支付 x+y 的代价。合成前后,史莱姆们的相对位置不会发生变化。
请你求出太郎君需要支付的总代价的最小值。
输入格式
输入以如下格式从标准输入读入:
N a1 a2 … aN
输出格式
输出太郎君需要支付的总代价的最小值。
显示翻译
题意翻译
输入输出样例
输入 #1复制
4 10 20 30 40
输出 #1复制
190
输入 #2复制
5 10 10 10 10 10
输出 #2复制
120
输入 #3复制
3 1000000000 1000000000 1000000000
输出 #3复制
5000000000
输入 #4复制
6 7 6 8 6 1 1
输出 #4复制
68
说明/提示
限制条件
- 所有输入均为整数。
- 2≤N≤400
- 1≤ai≤109
样例解释 1
可以按如下方式进行操作。用粗体表示正在合成的史莱姆。
- (10, 20, 30, 40) → (30, 30, 40)
- (30, 30, 40) → (60, 40)
- (60, 40) → (100)
样例解释 2
例如,可以按如下方式进行操作:
- (10, 10, 10, 10, 10) → (20, 10, 10, 10)
- (20, 10, 10, 10) → (20, 20, 10)
- (20, 20, 10) → (20, 30)
- (20, 30) → (50)
样例解释 3
答案可能无法用 32 位整数型表示。
样例解释 4
例如,可以按如下方式进行操作:
- (7, 6, 8, 6, 1, 1) → (7, 6, 8, 6, 2)
- (7, 6, 8, 6, 2) → (7, 6, 8, 8)
- (7, 6, 8, 8) → (13, 8, 8)
- (13, 8, 8) → (13, 16)
- (13, 16) → (29)
由 ChatGPT 4.1 翻译
思路
区间DP。
代码见下
#include<bits/stdc++.h>
using namespace std;
long long n,a[3001],a2[3001],f[3001][3001],op=-1e9-7;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
a2[i]=a2[i-1]+a[i];
}
memset(f,0x3f3f3f3f,sizeof(f));
for(int i=1;i<=n;i++) f[i][i]=0;
for(int i=2;i<=n;i++){
for(int l=1;l+i-1<=n;l++){
int r=l+i-1;
for(int k=l;k<=r-1;k++){
f[l][r]=min(f[l][r],f[l][k]+f[k+1][r]+a2[r]-a2[l-1]);
}
//cout<<l<<" "<<r<<" "<<f[l][r]<<endl;
}
}
cout<<f[1][n]<<endl;
return 0;
}

浙公网安备 33010602011771号