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

可以按如下方式进行操作。用粗体表示正在合成的史莱姆。

  • (1020, 30, 40) → (30, 30, 40)
  • (3030, 40) → (60, 40)
  • (6040) → (100)

样例解释 2

例如,可以按如下方式进行操作:

  • (1010, 10, 10, 10) → (20, 10, 10, 10)
  • (20, 1010, 10) → (20, 20, 10)
  • (20, 2010) → (20, 30)
  • (2030) → (50)

样例解释 3

答案可能无法用 32 位整数型表示。

样例解释 4

例如,可以按如下方式进行操作:

  • (7, 6, 8, 6, 11) → (7, 6, 8, 6, 2)
  • (7, 6, 8, 62) → (7, 6, 8, 8)
  • (76, 8, 8) → (13, 8, 8)
  • (13, 88) → (13, 16)
  • (1316) → (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;
}

posted @ 2025-10-22 21:12  bz02_2023f2  阅读(3)  评论(0)    收藏  举报  来源