本文主要是介绍【石子合并】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目
错解
#include <bits/stdc++.h>
using namespace std;
const int N = 310;
int a[N], s[N], f[N][N];
int main()
{int n;cin >> n;memset(f, 0x3f, sizeof f);for(int i = 1; i <= n; i++){cin >> a[i];s[i] = s[i-1] + a[i];f[i][i] = 0;}for(int i = 1; i < n; i++){for(int j = i+1; j <= n; j++){for(int k = i; k < j; k++){f[i][j] = min(f[i][j], f[i][k] + f[k+1][j] + s[j] - s[i-1]);}}}cout << f[1][n];
}
分析
应该从小区间遍历到大区间。因为这个更新方向是从小到大(先整合一小部分,再整合大部分),而不是从左到右、从上往下。
正解
#include <bits/stdc++.h>
using namespace std;
const int N = 310;
int a[N], s[N], f[N][N];
int main()
{int n;cin >> n;memset(f, 0x3f, sizeof f);for(int i = 1; i <= n; i++){cin >> a[i];s[i] = s[i-1] + a[i];f[i][i] = 0;}for(int len = 2; len <= n; len++){for(int i = 1; i + len -1 <= n; i++){int j = i + len - 1;for(int k = i; k < j; k++){f[i][j] = min(f[i][j], f[i][k] + f[k+1][j] + s[j] - s[i-1]);}}}cout << f[1][n];return 0;
}
这篇关于【石子合并】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!