[Rapport de résolution de problèmes] Résultat de la simulation du groupe B de la Coupe Blue Bridge 2020 du remplissage des espaces vides par un passager à l'ail: Apple

Description du problème

Il y a 3030 paniers et chaque panier contient plusieurs pommes, la séquence du nombre de pommes dans le panier a été donnée.

Maintenant, nous devons distribuer les pommes aux enfants: chaque enfant prendra trois pommes dans un panier ou une pomme dans chacun des trois paniers adjacents.

Apple peut rester, et différentes manières de tenir mèneront à des réponses différentes. Par exemple, pour la séquence 3 1 3, elle peut être affectée à deux enfants pour devenir 0 1 0, elle peut également être affectée à un enfant pour devenir 2 0 2. À ce stade, elle ne peut plus être divisée. La réponse est donc 22.

Pour la séquence suivante, combien d'enfants au maximum peut-on partager?


Tant que vous voulez le plus ou le moins, 95% sont les idées de recherche large ou de recherche profonde

Il existe de nombreux blogs sur Internet qui utilisent des solutions gourmandes, ce qui n'est pas du tout correct. Cette question est gourmande et ne peut donner que des exemples. Il est faux de changer les données avec des points délicats.

L'idée correcte est DFS. Il n'y a que deux opérations pour prendre le nombre, soit simple -3, soit trois adjacents -1, puis tant que vous utilisez la simulation de recherche profonde pour parcourir chaque possibilité, vous pouvez naturellement trouver le minimum.


Remarque: si vous utilisez simplement la recherche pour exécuter, chaque nombre doit prendre les deux adjacents moins un et prendre le nombre moins trois opérations, c'est-à-dire que vous devez exécuter 3 à la 30e puissance, pour l'ordinateur. Il est encore très lent, il doit donc être optimisé avec l'élagage.


Code de référence

#include<bits/stdc++.h>
using namespace std;

int ans = 0; 
int a[117] = {
    
    7,2,12,5,9, 9,8,10,7,10, 5,4,5,8,4, 4,10,11,3,8, 7,8,3,2,1, 6,3,9,7,1};
int sum[117];

void dfs(int idex, int num) {
    
    
	if(idex == 30) {
    
    
		ans = max(ans, num);
		return;
	}
	if(sum[idex] / 3 + num < ans) return; 	//剪枝优化
	//不公用
	dfs(idex+1, num+a[idex]/3);
	//往后公用 
	if(idex+2 < 30) {
    
    
		int min_num = min(a[idex], a[idex + 1]);
		min_num = min(min_num, a[idex+2]);		//共用最多能分几个
		for(int k = 1; k <= min_num; k++) {
    
    
			for(int i = 0; i < 3; i++) a[idex+i] -= k;
			dfs(idex+1, num+a[idex]/3+k);
			for(int i = 0; i < 3; i++) a[idex+i] += k;
		} 
	} 
}

int main() {
    
    
    for(int i = 29; i >= 0; i--) sum[i] = sum[i + 1] + a[i];
    for(int i = 0; i < 30; i++) cout << sum[i] << ' ';
    dfs(0, 0);
    cout << ans << endl;
    return 0;
}


L'avenir peut être attendu

Insérez la description de l'image ici

Je suppose que tu aimes

Origine blog.csdn.net/weixin_43899069/article/details/109098805
conseillé
Classement