282. Combinaison de pierres (intervalle dp)

Il y a N tas de pierres disposés en rangée, et leurs numéros sont 1, 2, 3, ..., N.

Chaque tas de pierres a une certaine qualité, qui peut être décrite par un nombre entier. Maintenant, ces tas de pierres NN doivent être fusionnés en un seul tas.

Seuls deux tas adjacents peuvent être fusionnés à chaque fois. Le coût de la fusion est la somme des masses des deux tas de pierres. Après la fusion, les pierres adjacentes aux deux tas de pierres seront adjacentes au nouveau tas. En raison de la ordre de sélection différent lors de la fusion, le coût total de la fusion est également différent.

Par exemple, s'il y a 44 tas de pierres  1 3 5 2, on peut d'abord fusionner 1 et 2 tas au coût de 4 pour obtenir  4 5 2, puis fusionner 1 et 2 tas au coût de 9 pour obtenir  9 2 , puis combiner pour obtenir 11, avec un coût total de 4+9+11= vingt-quatre ;

Si la deuxième étape consiste à fusionner d'abord 2 et 3 tas, le coût est de 7,  4 7le coût de la dernière fusion est de 11 et le coût total est de 4+7+11=22.

Le problème est le suivant : trouver une méthode raisonnable pour minimiser le coût total et produire le coût minimum.

format d'entrée

Un nombre NN dans la première ligne représente le nombre de tas NN de pierres.

La deuxième ligne contient les nombres NN, qui représentent la qualité de chaque tas de pierres (pas plus de 1000).

format de sortie

Affiche un entier représentant le coût minimum.

plage de données

1≤N≤300

Exemple d'entrée :

4
1 3 5 2

Exemple de sortie :

22

#include<bits/stdc++.h>
using namespace std;
const int N = 310;
int a[N];
const int INF = 0x3f3f3f;
int main() {
	int n;
	cin >> n;
	int dp[N][N];
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	int s[N];
	for (int i = 1; i <= n; i++) {
		s[i] = s[i - 1] + a[i];
	}
	int w[N][N];
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			w[i][j] = s[j] - s[i - 1];
		}
	}
	//有两种方法:
	for (int i = 1; i <= n; i++) {
		dp[i][i] = 0;//石子自己本身
	}
	for (int j = 2; j <= n; j++) { // 按区间进行划分
		for (int i = j - 1; i >= 1; i--) {
			//从 [i,j]
			dp[i][j] = INF;
			for (int k = i; k < j; k++) {
				dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j] + w[i][j]);
			}
		}
	}
	/*
	*按区间的大小进行划分
	* for(int len = 2;len <= n;len++){  //区间的长度[i,j],从小区间到大区间
		for(int i = 1; i <= n-len+1;i++){ // 区间的起点
			int j = i + len -1;
			dp[i][j]=INF;
			for(int k = i;k < j;k++){
				d[i][j] = min(dp[i][j],dp[i][j] + w[i][j]);
			}
		}
	}
	*/
	cout << dp[1][n];
	return 0;
}

Je suppose que tu aimes

Origine blog.csdn.net/zhi6fui/article/details/128574812
conseillé
Classement