石子合并问题(环形)
石子合并问题
Time Limit: 1000 ms Memory Limit: 65536 KiB
Problem Description
在一个圆形操场的四周摆放着n堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2 堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。试设计一个算法,计算出将n堆石子合并成一堆的最小得分和最大得分。
对于给定n堆石子,计算合并成一堆的最小得分和最大得分。
Input
输入数据的第1行是正整数n,1≤n≤100,表示有n堆石子。第二行有n个数,分别表示每堆石子的个数。
Output
输出数据有两行,第1行中的数是最小得分,第2行中的数是最大得分。
Sample Input
4
4 4 5 9
Sample Output
43
54
#include <bits/stdc++.h>
using namespace std;
int arr[205];
int dp_1[205][205],dp_2[205][205];
int sum[205];
int main()
{
int n,ans_min = 2e9,ans_max = -1,j;
sum[0] = 0;
cin>>n;
for(int i = 1; i <= n; i++)
{
cin>>arr[i];
sum[i] = sum[i-1] + arr[i];
}
//通过取余操作成环
for(int i = n+1; i <= 2*n; i++)
{
sum[i] = sum[i-1] + arr[i%n];
}
memset(dp_1,0,sizeof(dp_1));
memset(dp_2,0,sizeof(dp_2));
for(int m = 1; m < n; m++)
{
for(int i = 1; i < 2*n; i++)
{
j = i + m;
if(j >= 2*n)
break;
dp_2[i][j] = 2e9;
for(int k = i; k < j; k++)
{
dp_1[i][j] = max(dp_1[i][j],dp_1[i][k]+dp_1[k+1][j] + sum[j]-sum[i-1]);
dp_2[i][j] = min(dp_2[i][j],dp_2[i][k]+dp_2[k+1][j] + sum[j]-sum[i-1]);
}
}
}
for(int i = 1; i < 2*n; i++)
{
j = i + n-1;
if(j >= 2*n) break;
ans_max = max(ans_max,dp_1[i][j]);
ans_min = min(ans_min,dp_2[i][j]);
}
cout<<ans_min<<endl;
cout<<ans_max<<endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】