蓝桥杯 算法训练 车的放置
题目描述
- 资源限制
时间限制:1.0s 内存限制:256.0MB
- 问题描述
在一个n*n的棋盘中,每个格子中至多放置一个车,且要保证任何两个车都不能相互攻击,有多少中放法(车与车之间是没有差别的)
- 输入格式
包含一个正整数n
- 输出格式
一个整数,表示放置车的方法数
- 样例输入
2
- 样例输出
7
- 数据规模和约定
n<=8
- 【样例解释】一个车都不放为1种,放置一个车有4种,放置2个车有2种。
方案1 递归1
#include<iostream>
using namespace std;
int n;
bool flag[8];
int f(int i, bool flag[], int n){
if(i>n){
return 1;
}
int temp = 0;
for(int j=1; j<=n; j++){
if(!flag[j-1]){
flag[j-1] = true;
temp += f(i+1, flag, n);
flag[j-1] = false;
}
}
return temp + f(i+1, flag, n);
}
int main(){
cin>>n;
cout<<f(1, flag, n)<<endl;
return 0;
}
方案2 递归2 (可用记忆化搜索优化)
#include<iostream>
using namespace std;
int n;
int f(int i, int j, int k){
if(k==0){
return 1;
}else if(k==1){
return i*j;
}else{
int temp = 0;
for(int p=i-1; p>0; p--){
temp += j * f(p, j-1, k-1);
}
return temp;
}
}
int main(){
cin>>n;
int ans = 0;
for(int i=0; i<=n; i++){
ans += f(n, n, i);
}
cout<<ans<<endl;
return 0;
}
方案3 动态规划
#include<iostream>
using namespace std;
const int N=8;
int n;
int ans[N+1][N+1][N+1];
int main(){
cin>>n;
for(int i=1; i<=N; i++){
for(int j=i; j<=N; j++){
for(int k=0; k<=N; k++){
if(k>i){
break;
}
if(k==0){
ans[i][j][k] = 1;
}else if(k==1){
ans[i][j][k] = i * j;
}else{
for(int p=i-1; p>0; p--){
ans[i][j][k] += j * ans[p][j-1][k-1];
}
}
}
}
}
int temp = 0;
for(int i=0; i<=n; i++){
temp += ans[n][n][i];
}
cout<<temp<<endl;
return 0;
}