捡石子(区间dp问题)

状态表示: dp[l][r]合并l->r区间的最小代价
状态计算:
假设有这个一个k, l <= k < r ,使得dp[l][r]最小,
那么dp[l][r]就等于合并l->k, k+1 > r这两堆
dp[l][r] = dp[l][k] + dp[k + 1][r] + s[r] - s[l - 1]
顺便记忆一下区间dp模板

for(int len = 2; len <= n; len ++)//区间长度
  for(int l = 1; l + len - 1 <= n; l ++)//左端点
   {
      int r = l + len - 1;//右端点
      for(int k = l; k < r; k ++)//区间分割点
    }
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
const int N = 310;
int dp[N][N];
int s[N];
int main()
{
    ios::sync_with_stdio(0);cin.tie(0);
    int n;
    cin >> n;
    for(int i = 1; i <= n; i ++)cin >> s[i], s[i] += s[i - 1];
    for(int len = 2; len <= n; len ++)
    {
        for(int l = 1; l + len - 1 <= n; l ++)
        {
            int r = l + len - 1;
            dp[l][r] = 1e9;
            for(int k = l; k < r; k ++)
            {
                dp[l][r] = min(dp[l][r], dp[l][k] + dp[k + 1][r] + s[r] - s[l - 1]);
            }
        }
    }
    cout << dp[1][n] << endl;
}
posted @ 2021-08-26 10:04  梨花满地  阅读(43)  评论(0)    收藏  举报