捡石子(区间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;
}

浙公网安备 33010602011771号