#include<iostream>
#include<algorithm>
using namespace std;
int n;
const int maxn=1000;
const int INF = 0x3f;
int a[maxn]={0};
int dp[maxn][maxn]={0};
int dp1[maxn][maxn]={0};
int sum[maxn]={0};
int main()
{
cin>>n;
sum[0]=0;
for(int i=1;i<=n;i++){
cin>>a[i];
sum[i]+=(a[i]+sum[i-1]);//预处理化数据,将任取两堆的石子合并(相当于前缀和)
}
for(int r=1;r<n;r++){
for(int i=1;i<n;i++){
int j=i+r;
dp[i][j]=INF;
for(int k=i;k<=j;k++){
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]);//dp[i][j]为取从第i到k堆和第k+1堆到j堆的石子的最小值
}
dp[i][j]+=sum[j]-sum[i-1];//dp[i][j]再加上你所取的石子的总数和
}
}
cout<<dp[1][n]<<endl;//输出的dp[1][n]就为最小的石子堆
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cout<<dp[i][j]<<" ";
}
cout<<endl;
}
for(int r=1;r<n;r++){
for(int i=1;i<n;i++){
int j=i+r;
for(int k=i;k<=j;k++){
dp1[i][j]=max(dp1[i][j],dp1[i][k]+dp1[k+1][j]);
}
dp1[i][j]+=sum[j]-sum[i-1];
}
}
cout<<dp1[1][n]<<endl;//同理dp1[i][j]就为最大的石子的堆的值
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cout<<dp1[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
石子合并问题
最新推荐文章于 2023-11-12 12:31:54 发布