ProgramAlgTrain/20240919/CSP常考算法模板/区间dp/区间dp_合并石子.cpp
2024-09-19 11:25:26 +08:00

57 lines
1014 B
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <bits/stdc++.h>
using namespace std;
int a[101];
int sum[101]; // prefix sum
int f[101][101];
/*
区间动态规划解题步骤:
1.根据问题推测dp[i][j]的含义
问题是把第1堆到第n堆石子合成一堆最小的得分
dp[i][j]的含义把第i堆到第j堆石子合成一堆最小的得分
2.根据规则推出dp[i][j]的状态转移公式
在i-j之间选一个中间值k
dp[i][j] = dp[i][k] + dp[k+1][j] + ( sum[j] - s[i-1] );
3.边界问题比如设定dp[0][0],dp[0][j],dp[i][0],dp[i][j],dp[i][i]初始值)
*/
/*
input
7
13
7
8
16
21
4
18
output
239
*/
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin>>n;
for(int i=1; i<=n; i++) {
cin>>a[i];
sum[i] = sum[i-1] + a[i];
}
for(int i=n-1; i>=1; i--) { //一定要逆序
for(int j=i+1; j<=n; j++) {
f[i][j] = INT_MAX;
for(int k=i; k<=j-1; k++) {
f[i][j] = min(f[i][j], f[i][k]+f[k+1][j] + sum[j]-sum[i-1]);
}
}
}
cout<<f[1][n]<<endl;
return 0;
}