top1编程
← 返回题目
题解

【入门】合并石子

1 条题解

  • 0
    @ 2026-7-29 0:19:10
    #include <iostream> 
    #include <cstring> 
    using namespace std;
    const int N = 310; 
    int n; 
    int a[N], s[N]; // s数组用于前缀和优化
    int f[N][N]; // f[i][j]表示合并第i~j堆石子的最小代价
     
    int main() { 
    	cin >> n; 
    	for (int i = 1; i <= n; i ++ ) 
    		cin >> a[i];
     
    	// 前缀和优化
    	for (int i = 1; i <= n; i ++ ) 
    		s[i] = s[i - 1] + a[i];
    	
    	memset(f, 0x3f, sizeof f); // 初值无穷大
    	for (int i = 1; i <= n; i ++ ) 
    		f[i][i] = 0; // 一堆石子不需要合并
    	
    	// 枚举区间长度
    	for (int len = 2; len <= n; len ++ )
    	{
    	    // 枚举区间起点
    	    for (int i = 1; i + len - 1 <= n; i ++ )
    	    {
    	        int j = i + len - 1; // 区间终点
    	
    	        // 枚举划分位置
    	        for (int k = i; k < j; k ++ )
    	        {
    	            f[i][j] = min(f[i][j], f[i][k] + f[k + 1][j] + s[j] - s[i - 1]);
    	        }
    	    }
    	}
    	
    	cout << f[1][n] << endl;	
    	return 0;
    }
    
    • 1