区间dp

这一题我没有做出来

关键是我想不到,如何设置断点。
因此我就无法写出状态转移方程。
正确答案中的断点设置是dp[i][j] 枚举i是第k个出场的

这真的十十分的巧妙

换句话说,既然是区间dp那么就一定是可以设置断点的。

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int inf = 1e9;
int n,a[110],dp[110][110],sum[110];
int main(){
    int T;scanf("%d",&T);
    for (int tcase=1;tcase<=T;++tcase){
        scanf("%d",&n);
        for (int i=1;i<=n;++i)scanf("%d",&a[i]);
        for (int i=1;i<=n;++i)sum[i]=sum[i-1]+a[i];
        for (int p=1;p<=n;++p){
            for (int i=1,j=i+p-1;j<=n;++i,++j){
                dp[i][j]=inf;
                for (int k=1;k<=p;++k){
                    dp[i][j]=min(dp[i][j],dp[i+1][i+k-1]+(k-1)*a[i]+dp[i+k][j]+(sum[j]-sum[i+k-1])*k);
                }
            }
        }printf("Case #%d: %d\n",tcase,dp[1][n]);
    }
}