for(int k=l+1;k<r;k++)
f[l][r]=max(f[l][r],f[l][k]+f[k][r]+a[l]*a[r]*a[k]);
这是能量项链
为什么从l+1到r-1还有为什么是f[l][k]+f[k][r]
for(int k=l;k<r;k++)
f[l][r]=min(f[l][r],f[l][k]+f[k+1][r]+s[r]-s[l-1]);
这是石子合并
为什么不是从l+1开始到r-1; 还有这个为什么是f[l][k]+f[k+1][r]; 能量项链
#include<iostream>
#include<algorithm>
using namespace std;
const int N=405;
int n,ans;
int a[N/2],f[N][N];
int main(){
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
a[i+n]=a[i];//对待环形问题的方法
}
for(int len=2;len<=2*n;len++)//区间长度寄两个之间的距离 (想要合并的 不是两个 是目标)
for(int i=1;i+len-1<=2*n;i++)//起点
{
int l=i,r=i-1+len;
for(int k=l+1;k<r;k++)//区间最后一个合并位置
f[l][r]=max(f[l][r],f[l][k]+f[k][r]+a[l]*a[r]*a[k]);
}
for(int i=1;i<=n;i++)
ans=max(ans,f[i][i+n]);//从任意位置开始合成的
cout<<ans;
return 0;
}
石子合并
#include<iostream>
#include<algorithm>
using namespace std;
const int N=310;
int n;
int s[N];
int f[N][N];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&s[i]);
for(int i=1;i<=n;i++)s[i]+=s[i-1];
for(int len=2;len<=n;len++)
for(int i=1;i+len-1<=n;i++)
{
int l=i,r=i+len-1;
f[l][r]=1e8;
for(int k=l;k<r;k++)
f[l][r]=min(f[l][r],f[l][k]+f[k+1][r]+s[r]-s[l-1]);
}
printf("%d",f[1][n]);
return 0;
}