群文件(递归)中:
分身回溯时需要改回去的那些文件称为回溯项:回溯项分为两种:状态项 & 决策项(自己取的)
状态项是递归时每经过一个状态所改变的群文件
决策项是递归时每做一个决策时所改变的群文件
有一些群文件啥都不是,判断方法:
分身回溯时要不要改回去,不用的是啥都不是
一个回溯项判断是决策项还是状态项,看起点时要不要改变他,要的是状态项。
重要*100偷懒大技巧:派出分身时暂时先不判断能不能走,而是先让分身走过去看一看,如果此路不通就让分身回去。
复习:棋盘,大楼选数,全排列
大楼选数
#include<iostream>
typedef long long Int;
constexpr Int MAXN=8,MAXM=6;
Int N,M,a[MAXN+1][MAXM],count=0,sum=0;//有两个群文件叫做count(啥的不是的群文件)和sum(状态项)
void fenshen(Int i){
if(i<=N){//没在终点
for(Int j=0;j<M;j++){
sum+=a[i][j];//更新决策项
fenshen(i+1);//派出下一个分身去下一楼,自己在原地等它回来
sum-=a[i][j];//恢复决策项
}
}else{//在终点
count+=sum%2==0;//更新群文件
}
}
int main(){
std::cin>>N>>M;
for(Int i=0;i<N;i++){
for(Int j=0;j<M;j++){
std::cin>>a[i][j];
}
}
fenshen(1);
std::cout<<count;
return 0;
}
全排列:
#include <iostream>
typedef long long Int;
constexpr Int MAXN = 8;
Int N;
Int keng[1 + MAXN];
bool yongguo[1 + MAXN]{};
void fenshen(Int a) {
if(!yongguo[keng[a]]){}else return;
if (a > N) {//如果a在终点,那么输出
for (Int j = 1; j <= N; j++) {
std::cout << keng[j] << ' ';
}
std::cout << std::endl;
} else {//a没到终点
for (keng[a] = 1; keng[a] <= N; keng[a]++) {//for决策
yongguo[keng[a]]=true;//更新决策项
fenshen(a+1);//分身去下一个keng
yongguo[keng[a]]=false;//还原决策项
}
}
}
int main(){
std::cin>>N;
fenshen(1);
return 0;
}
棋盘:
#include <iostream>
typedef long long Int;
constexpr Int MAX_N=100;
constexpr Int MAX_M=100;
Int N,M;
Int count=0;
bool zouguo[1+MAX_N][1+MAX_M]{};
void fenshen(Int i,Int j){
zouguo[i][j]=true;
//分身出生的第一件事:环顾四周看看我在哪
if(i==N&&j==M){//如果我在终点
count++;//更新群文件
}else{
//看看自己能往哪走
if(j+1<=M && !zouguo[i][j+1]){//能往右走
fenshen(i,j+1);
}
if(i+1<=N && !zouguo[i+1][j]){//能往下走
fenshen(i+1,j);
}
if(j-1>=1 && !zouguo[i][j-1]){//能往左走
fenshen(i,j-1);
}
if(i-1>=1 && !zouguo[i-1][j]){//能往上走
fenshen(i-1,j);
}
}
zouguo[i][j]=false;
}
int main(){
std::cin>>N>>M;
fenshen(1,1);
std::cout<<count;
}
函数默认:
比如
#include<iostream>
typedef long long Int;
bool f(double i,char j='A'){
}
int main(){
f(1);
f(1,'O');
}
这样的话主函数里面第一个调用f的参数为1,A(自动在函数里面定义好了,如果手动填了自己就被覆盖掉 注意:默认的参数只能填在右边),而第二个调用f的参数是1,O
动态存储变量:使用方法:new 要定义的类型
它没有名字,但是存续期很灵活
需要把它的值存起来要用一个指针去指向它
它可以手动被删掉,也可以自动在程序结束之后与全局变量一起被删掉
如果你忘记存它了它就用不了但是还是存在在程序里面
注意:new Int是一个表达式
比如:
void f(){
int *p=new int;
*p=200;
}
int main(){
return 0;
}
这里我们把new Int 的值转换成指针之后使用