Offer Offre Sword Finger】 —— Programmation dynamique et algorithme gourmand dérivé du problème de coupe de corde

Exigences du sujet

Donnez-vous une corde de longueur n, veuillez couper la corde en m longueurs de longueur entière (m et n sont des entiers, n> 1 et m> 1), la longueur de chaque corde est notée k [0], k [1], ..., k [m]. Quel est le produit maximal possible de k [0] xk [1] x ... xk [m]? Par exemple, lorsque la longueur de la corde est de 8, nous la coupons en trois sections de longueur 2, 3 et 3, respectivement, et le produit maximum obtenu à ce moment est 18.

1. Analyse et solution de programmation dynamique

Jetons d'abord un coup d'œil à la programmation dynamique. Quels problèmes généraux sont résolus en utilisant la programmation dynamique?
Si le problème cherche la solution optimale à un problème, et le problème peut être décomposé en plusieurs sous-problèmes, et il y a des sous-problèmes plus petits qui se chevauchent.

Caractéristiques:

  1. La solution optimale du problème global est la solution optimale qui dépend de chaque problème
  2. Décomposer les gros problèmes en plusieurs petits problèmes, et il y a des sous-problèmes plus petits qui se chevauchent
  3. Analysez le problème de haut en bas et résolvez le problème de bas en haut

Ensuite, en utilisant l'idée de programmation dynamique, réfléchissons à la façon de couper la corde.
Insérez la description de l'image ici
Par conséquent, nous savons que f (1) = 1, f (2) = 1, f (3) = 2.

Nous stockons la solution optimale du sous-problème dans les produits du réseau. Le i-ème élément du tableau représente la valeur maximale du produit de longueur de chaque segment après avoir coupé la corde de longueur i en plusieurs segments, qui est f (i). L'
implémentation du code est la suivante:

int maxproductAfterCutting(int length)
{
	if (length < 2)
		return 0;
	if (length == 2)
		return 1;
	if (length == 3)
		return 2;

	int* products = new int[length + 1];
	products[0] = 0;
	products[1] = 1;
	products[2] = 2;
	products[3] = 3;

	int max = 0;
	for (int i = 4; i <= length; i++)
	{
		max = 0;
		for (int j = 1; j < i / 2; j++)
		{
			int product = products[i] * products[i - j];
			if (max < product)
				max = product;

			products[i] = max;
		}
	}
	max = products[length];
	delete[] products;
	return max;
}

2. Algorithme gourmand

L'idée de base de l'algorithme gourmand est. Lorsque nous utilisons l'algorithme gourmand pour résoudre le problème, chaque étape peut faire un choix gourmand. Sur la base de ce choix, nous déterminons que nous pouvons obtenir la solution optimale.

Lorsque n> = 5, nous coupons le plus possible de corde de longueur 3. Lorsque la longueur de corde restante est de 4, coupez la corde en deux longueurs de corde.

int maxproductAfterCutting1(int length)
{
	if (length < 2)
		return 0;
	if (length == 2)
		return 1;
	if (length == 3)
		return 2;

	//尽可能多的剪去长度为3的绳子段
	int timeOf3 = length / 3;

	//当绳子最后剩下的长度为4的时候,不能再剪去长度为3的绳子段
	//此时更好的方法就是把绳子剪成长度为2的两段
	if (length - timeOf3 * 3 == 1)
		timeOf3 -= 1;

	int timeOf2 = (length - timeOf3 * 3) / 2;
	return (int)(pow(3, timeOf3)) * (int)(pow(2, timeOf2));
}

Alors pourquoi choisir ce genre de pensée?
Lorsque n> = 5, nous pouvons prouver que 2 (n-2)> n et 3 (n-3)> n, c'est-à-dire lorsque la longueur de la corde restante est supérieure ou égale à 5, nous le couperons En 3 ou 2 longueurs de corde.
Lorsque n> 5, 3 (n-3)> = 2 (n-2), nous devons donc couper autant de longueurs de corde que possible.

Publié 98 articles originaux · a gagné les éloges 9 · vues 3653

Je suppose que tu aimes

Origine blog.csdn.net/qq_43412060/article/details/105357429
conseillé
Classement