4.6

文章讨论了递归过程中的群文件(如count和sum)管理,区分状态项和决策项,以及在分身回溯中如何判断和处理这些变化。举例了大楼选数、全排列和棋盘问题的代码,涉及默认参数和动态存储的使用。
摘要由CSDN通过智能技术生成

群文件(递归)中:

分身回溯时需要改回去的那些文件称为回溯项:回溯项分为两种:状态项 & 决策项(自己取的)

状态项是递归时每经过一个状态所改变的群文件

决策项是递归时每做一个决策时所改变的群文件

有一些群文件啥都不是,判断方法:

分身回溯时要不要改回去,不用的是啥都不是

一个回溯项判断是决策项还是状态项,看起点时要不要改变他,要的是状态项。

重要*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 的值转换成指针之后使用

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值