石子合并

解题思路
区间DP模板题。前缀和优化。
code
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n;
int a[210];
int s[210];
int f[210][210];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
memset(f,0x3f3f3f3f,sizeof(f));
for(int i=1;i<=n*2;i++)
f[i][i]=0;
for(int i=1;i<=n;i++)
s[i]=s[i-1]+a[i];
for(int i=n+1;i<=2*n;i++)
s[i]=s[i-1]+a[i-n];
for(int len=2;len<=n;len++)
for(int l=1;l+len-1<=2*n;l++)
{
int r=l+len-1;
for(int k=l;k<r;k++)
f[l][r]=min(f[l][r],f[l][k]+f[k+1][r]);
f[l][r]+=s[r]-s[l-1];
}
int ans=0x3f3f3f3f;
for(int i=1;i<=n;i++)
ans=min(ans,f[i][i+n-1]);
cout<<ans<<endl;
memset(f,0,sizeof(f));
for(int len=2;len<=n;len++)
for(int l=1;l+len-1<=2*n;l++)
{
int r=l+len-1;
for(int k=l;k<r;k++)
f[l][r]=max(f[l][r],f[l][k]+f[k+1][r]);
f[l][r]+=s[r]-s[l-1];
}
ans=0;
for(int i=1;i<=n;i++)
ans=max(ans,f[i][i+n-1]);
cout<<ans<<endl;
}

本文介绍了一道经典的区间动态规划题目“石子合并”的解题思路与代码实现。通过对前缀和进行优化,有效地解决了该问题。文章提供了两段代码示例,分别展示了求最小值与最大值的过程。
715

被折叠的 条评论
为什么被折叠?



