石子合并是个经典的区间DP模型,然而之前并没有做过。。。
关于石子合并可以看下这个博客:
https://blog.csdn.net/riba2534/article/details/76045531
代码如下:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#define mem(a,b) memset(a,b,sizeof(a));
using namespace std;
typedef long long ll;
const ll inf=1e18;
ll a[210],sum[210];
ll dp1[210][210],dp2[210][210];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;++i)
{
cin>>a[i];
a[n+i]=a[i]; //因为原题是个环,所以我们将整个数组在[1+n,n+n]复制一遍
}
sum[0]=0;
for(int i=1;i<=2*n;++i) //sum[i]记录[1,i]的石子总数
sum[i]=sum[i-1]+a[i];
mem(dp1,0);
for(int i=0;i<=2*n;++i)
for(int j=0;j<=2*n;++j)
dp2[i][j]=inf;
for(int i=1;i<=2*n;++i) dp2[i][i]=0;
for(int i=2*n-1;i>=1;--i) //枚举起点
{
for(int j=i+1;j-i<n&&j<=2*n;++j) //枚举[i,j]区间
{
for(int k=i;k<j;++k) //枚举划分线,将石子划分成[i,k],[k+1,j]
{
dp1[i][j]=max(dp1[i][j],dp1[i][k]+dp1[k+1][j]+sum[j]-sum[i-1]);
dp2[i][j]=min(dp2[i][j],dp2[i][k]+dp2[k+1][j]+sum[j]-sum[i-1]);
}
}
}
ll ans1=0,ans2=inf;
for(int i=1;i<=n;++i)
{
ans1=max(ans1,dp1[i][i+n-1]);
ans2=min(ans2,dp2[i][i+n-1]);
}
cout<<ans2<<endl<<ans1<<endl;
return 0;
}
还有另外一种解题方法,跟上面有相似的地方,见代码。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cmath>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=2e2+5;
int dp1[maxn][maxn],dp2[maxn][maxn];
int a[maxn],sum[maxn];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;++i)
{
cin>>a[i];
a[i+n]=a[i];
}
sum[0]=0;
for(int i=1;i<=2*n;++i)
sum[i]=sum[i-1]+a[i];
mem(dp1,0); mem(dp2,inf);
for(int i=1;i<=2*n;++i) dp2[i][i]=0;
for(int k=1;k<=n-1;++k) //枚举合并石子的次数
{
for(int i=1;i<=2*n-k;++i) //枚举起点
{
int j=i+k; //合并次数与起点都确定了,终点也随之确定
for(int l=i;l<j;++l) //枚举分割线
{
dp1[i][j]=max(dp1[i][j],dp1[i][l]+dp1[l+1][j]+sum[j]-sum[i-1]);
dp2[i][j]=min(dp2[i][j],dp2[i][l]+dp2[l+1][j]+sum[j]-sum[i-1]);
}
}
}
int ans1=0,ans2=inf;
for(int i=1;i<=n;++i)
{
ans1=max(ans1,dp1[i][i+n-1]);
ans2=min(ans2,dp2[i][i+n-1]);
}
cout<<ans2<<"\n"<<ans1<<endl;
return 0;
}
两种方法时间复杂度都是差不多的,可任选一种做。