POJ1651 Multiplication Puzzle (区间dp)
这题一看就跟石子合并的类型相似,但是我们对状态的定义需要略加改变
因为我们观察到头和尾是不能删除的
我们定义f[l][r]为不删除头尾的情况下的最小值
这样我们就能枚举最后一次删的是哪个点了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #include<vector> #include<string> #include<cstring> #include<map> #include<set> using namespace std; typedef long long ll; const int N=1e5+10; const int inf=0x3f3f3f3f; int f[110][110]; int a[N]; int main(){ int i; int n; cin>>n; for(i=1;i<=n;i++){ scanf("%d",&a[i]); } memset(f,0x3f,sizeof f); for(i=1;i<=n-1;i++){ f[i][i+1]=0; } int len,l,r; int k; for(len=3;len<=n;len++){ for(l=1;l+len-1<=n;l++){ r=l+len-1; for(k=l+1;k<r;k++){ f[l][r]=min(f[l][r],f[l][k]+f[k][r]+a[k]*a[l]*a[r]); } } } cout<<f[1][n]<<endl; }
没有人不辛苦,只有人不喊疼