1. 程式人生 > >N皇后問題(遞迴和動態規劃)

N皇后問題(遞迴和動態規劃)

說明:內容摘錄自左程雲的《程式設計師程式碼面試指南》

一:題目描述

N皇后問題是指N*N的棋盤要擺N個皇后,要求任何兩個皇后不同行、不同列、也不在同一條斜線(兩個皇后成45度)上。給定一個整數n,返回n皇后的擺法有多少種。

二:解題思路

如果在(i,j)位置(第i行第j列)放置一個皇后,接下來在哪些位置不能放置皇后呢?

1、整個第i行的位置都不能放置

2、整個第j列的位置都不能放置

3、如果位置(a,b)滿足|a-i|==|b-j|,說明(a,b)與(i,j)處在同一條斜線上,也不能放置

把遞迴過程直接設計成逐行放置皇后的方式,可以避開1的那些不能放置的位置。

接下來用一個數組儲存已經放置的皇后位置,假設陣列為record,record[i]表示第i行皇后所在的列數。

在遞迴計算到第i行第j列時,檢視record[0..k](k<i)的值:

1、看是否有j相等的值,若有說明(i,j)不能放置皇后,

2、再看是否有|k-i|==|recor[k]-j|,若有,也說明(i,j)不能放置皇后。

三:程式碼實現

#include<iostream>
#include<vector>
using namespace std;

bool isValid(int* record, int i, int j){
	for (int k = 0; k < i;k++)
	if (j == record[k] || abs(record[k] - j) == abs(i - k))
		return false;
	return true;
}

int process(int i, int* record, int n){
	if (i == n)  //搜尋完所有行,說明本次方案可以滿足皇后的擺法
		return 1;

	int res = 0;

	for (int j = 0; j < n; j++){  //對於第i行,每一列都可能是皇后的擺放位置
		if (isValid(record, i, j)){ //如果該列滿足條件,遞迴尋找下一行皇后可以擺放的位置
			record[i] = j;
			res += process(i + 1, record, n);
		}
	}
	return res;
}
int num1(int n){
	if (n < 1)
		return 0;
	int * record = new int[n]; //儲存每一行皇后儲存的列數
	int res = process(0, record, n);

	delete record;
	return res;

}
int main(){

	int n = 8;
	for (int n = 1; n < 16;n++)
		cout <<n<<"皇后	的擺法:"<< num1(n) << endl;

	system("pause");
	return 0;
}
N從1-15的結果(等呀等~): 1皇后   的擺法:1
2皇后   的擺法:0
3皇后   的擺法:0
4皇后   的擺法:2
5皇后   的擺法:10
6皇后   的擺法:4
7皇后   的擺法:40
8皇后   的擺法:92
9皇后   的擺法:352
10皇后  的擺法:724
11皇后  的擺法:2680
12皇后  的擺法:14200
13皇后  的擺法:73712
14皇后  的擺法:365596
15皇后  的擺法:2279184

相關推薦

N皇后問題動態規劃

說明:內容摘錄自左程雲的《程式設計師程式碼面試指南》 一:題目描述 N皇后問題是指N*N的棋盤要擺N個皇后,要求任何兩個皇后不同行、不同列、也不在同一條斜線(兩個皇后成45度)上。給定一個整數n,返回n皇后的擺法有多少種。 二:解題思路 如果在(i,j)位置(第i行第j

LeetCode刷題Easy篇爬樓梯問題動態規劃問題

題目 You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb 1 or 2 steps. In how many distinc

9.9動態規劃——列印n對括號的全部有效組合即左右括號正確配對

/**  * 功能:列印n對括號的全部有效組合(即左右括號正確配對)。 */ 兩種方法: 方法一: /** * 思路:在括號的最前面或者原有的每對括號裡面插入一對括號。至於其他任意位置,比如字

LeetCode刷題Easy篇斐波那契數列問題,尾,非動態規劃解法

題目 斐波那契數列:  f(n)=f(n-1)+f(n-2)(n>2) f(0)=1;f(1)=1;  即有名的兔子繁衍問題  1 1 2 3 5 8 13 21 .... 我的解法 遞迴 public static int Recursion

動態規劃

換錢的方法數 題目:給定陣列arr, arr中所有的值都為正數且不重複。每個值代表一種面值貨幣,每種面值的貨幣可以使用任意張,再給定一個整數aim代表要找的錢數,求換錢有多少種方法。 解題思路: 解法一:暴力遞迴 如果arr={5,10,25,1}, aim=1000,過程

動態規劃專題----劍指offer+左程雲演算法

遞迴和動態規劃專題(一)–劍指offer+左程雲演算法 (一).斐波那契專題 【題目】大家都知道斐波那契數列,現在要求輸入一個整數n,請你輸出斐波那契數列的第n項。 n<=39   毫無疑問,大家能想到這個公式:F(n)=F(n-1)+F

leetcode 746.爬樓梯的最小代價從暴力動態規劃

題目: On a staircase, the i-th step has some non-negative cost cost[i] assigned (0 indexed). Once you pay the cost, you can either cl

最大連續子序列動態規劃

問題描述: 給定一個整數序列,a0, a1, a2, …… , an(項可以為負數),求其中最大的子序列和。如果所有整數都是負數,那麼最大子序列和為0; 方法一: 用了三層迴圈,因為要找到這個子序列,肯定是需要起點和終點的,所以第一層迴圈確定起點,第二層迴圈確定終點,第三層

動態規劃

     遞迴演算法就是通過解決同一問題的一個或多個更小的例項來最終解決一個大問題的演算法。為了在C語言中實現遞迴演算法,常常使用遞迴函式,也就是說能呼叫自身的函式。遞迴程式的基本特徵:它呼叫自身(引數的值更小),具有終止條件,可以直接計算其結果。       在使用遞迴程式

DataWhale——動態規劃

本文大量參考了部落格演算法-動態規劃 Dynamic Programming--從菜鳥到老鳥裡的內容,加上一點自己的理解。 遞迴 遞迴和動態規劃很是相近,但又有所區別。從定義上看,遞迴在數學上可以表示為“數學歸納法”;由於我個人對數學歸納法的解法實在是印象深刻,但凡遇到之類的問題,都會用數學老師

Python練習(1):動態規劃的簡單應用

首先考慮一個問題,假如我們在某個編譯器上寫出了這樣的式子:(i++)(i++)(i++),假設i = 5,那麼會有多少可能的結果? 顯然,編譯器對這種行為是未定義的,我們不知道i自增和乘法指令的執行順序,可能的結果有5*5*5, 5*5*6, 5*5*7, 5

N皇后演算法

#include<bits/stdc++.h>using namespace std;int c=0;int cheak(int x[],int nowhang){//判斷是否在同一列,在對角 int i;for(i=1;i<nowhang;i++)if(x[i]==x[nowhang]||

演算法-N皇后

package MOOC; /** * 輸入整數n,要求n個國際皇后,擺在n*n的棋盤上,使其互相不能攻擊(不在同一行列對角線上),輸出全部方案 */ import java.util.Scann

第四章動態規劃(一)

1,斐波那契數列問題的遞迴和動態規劃 補充題目1: 給定整數n,代表臺階數,1次可以跨2個或者1個臺階,返回有多少種走法。 舉例:n=3,可以三次都跨一個臺階;也可以先跨2個臺階,再跨一個臺階;還可以先跨1一個臺階,再跨兩個臺階。所

N皇后經典演算法

一、N皇后 1、題目 將n個皇后擺放在N*N的棋盤中,互相不可攻擊,有多少種擺放方式,每種擺放方式具體是怎樣的? 2、解題思路 解題思路: 1、將棋盤放在一個二維陣列中,同時設定方向陣列: static const int dx[]

簡單整數劃分法+動態規劃法

整數劃分: 所謂整數劃分,就是將一個數n寫成正整數相加的形式,如3可以劃分為1+1+1,1+2,3等三種情況,而f(n,m)則表示,劃分數中最大的數小於m時n的劃分。如f(3,2)就是1+1+1,1+

全排列的不同方式STL演算法

#include<iostream> #include<cstdlib> #include<algorithm> #include<iomanip> #include<functional> #include<iterator>

leetcode 53. 最大子序分治法動態規劃

給定一個整數陣列 nums ,找到一個具有最大和的連續子陣列(子陣列最少包含一個元素),返回其最大和。示例:輸入: [-2,1,-3,4,-1,2,1,-5,4], 輸出: 6 解釋: 連續子陣列 [4,-1,2,1] 的和最大,為 6。 進階:如果你已經實現複雜度為 O(n

Java下實現無重字串的全排列回溯方法

開發十年,就只剩下這套架構體系了! >>>   

9.9動態規劃——N皇後

其它 ace req case create lac any urn distance /** * 功能:打印八皇後在8*8棋盤上的各種擺法。當中每一個皇後都不同行、不同列,也不在對角線上。 * 這裏的“對角線”指的是全部的對角線,不僅僅是平分整個棋盤的那兩