补了俩天,总算把线性DP写了一半,剩下的等抽个时间慢慢写。
区间dp就是在区间上进行动态规划,求解一段区间上的最优解。主要是通过合并小区间的 最优解进而得出整个大区间上最优解的dp算法。(个人觉得所有的DP都是很美的暴力枚举…)
石子合并
//这里有一个板子的思路供大家参考
for(int len = 1;len<=n;len++) //枚举长度
{
for(int j = 1;j+len<=n+1;j++) //枚举起点,ends<=n
{
int start=j;int ends = j+len - 1;
for(int i = start;i<ends;i++) //枚举分割点,更新小区间最优解
{
dp[start][ends] = min(dp[start][ends],dp[start][i]+dp[i+1][ends]+something);
}
}
}
#include<iostream>
#include<algorithm>
using namespace std;
const int N=310;
int n;
int s[N];
int f[N][N];
int main(){
cin.tie(0);
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++)cin>>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]);
}
}
cout<<f[1][n]<<endl;
return 0;
}
后续的练习题等找个时间。