程序设计算法实验指导 回溯Word文档下载推荐.docx

上传人:b****7 文档编号:22035393 上传时间:2023-02-02 格式:DOCX 页数:11 大小:99.46KB
下载 相关 举报
程序设计算法实验指导 回溯Word文档下载推荐.docx_第1页
第1页 / 共11页
程序设计算法实验指导 回溯Word文档下载推荐.docx_第2页
第2页 / 共11页
程序设计算法实验指导 回溯Word文档下载推荐.docx_第3页
第3页 / 共11页
程序设计算法实验指导 回溯Word文档下载推荐.docx_第4页
第4页 / 共11页
程序设计算法实验指导 回溯Word文档下载推荐.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

程序设计算法实验指导 回溯Word文档下载推荐.docx

《程序设计算法实验指导 回溯Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《程序设计算法实验指导 回溯Word文档下载推荐.docx(11页珍藏版)》请在冰豆网上搜索。

程序设计算法实验指导 回溯Word文档下载推荐.docx

j++)

if((abs(k-j)==abs(x[j]-x[k]))||(x[j]==x[k]))/*x[i]表示皇后i放在棋盘的第i行的第x[i]列*/

return0;

/*能攻击到其他皇后,返回0*/

return1;

/*不能攻击到其他皇后,返回1*/

}

voidBacktrack(intt,intn,int*x)

/*递归回溯求解*/

inti;

if(t>

n)

sum++;

/*输出一个方案*/

printf("

方案%d:

"

sum);

for(i=1;

i<

=n;

i++)

(%d,%d)"

i,x[i]);

\n"

);

else

x[t]=i;

if(Place(t,x))Backtrack(t+1,n,x);

/*如果新加入第t个皇后所在的位置i没有与其他皇后的位置冲突,则进入解空间子树,试探第t+1个皇后的位置;

否则不进入子树,舍弃该段子树,即进行剪枝*/

main()

intn,*x;

请输入皇后的个数:

scanf("

%d"

&

n);

x=(int*)malloc((n+1)*sizeof(int));

/*x[0]未使用*/

以下每个方案都表示出了%d个皇后在棋盘上的坐标\n\n"

n);

Backtrack(1,n,x);

/*求解*/

总共有%d种方案\n"

}

2.桥本分数式(具体题目见书P34),并输出解的个数。

回溯实现:

voidmain()

{intg,i,k,s,a[10];

longm1,m2,m3;

i=1;

a[1]=1;

s=0;

while

(1)

{g=1;

for(k=i-1;

k>

=1;

k--)

if(a[i]==a[k]){g=0;

break;

}//两数相同,标记g=0

if(i==9&

&

g==1&

a[1]<

a[4])

{m1=a[2]*10+a[3];

m2=a[5]*10+a[6];

m3=a[8]*10+a[9];

if(a[1]*m2*m3+a[4]*m1*m3==a[7]*m1*m2)//判断等式

{s++;

(-)"

s);

%d/%ld+%d/"

a[1],m1,a[4]);

%ld=%d/%ld"

m2,a[7],m3);

if(s%2==0)printf("

if(i<

9&

g==1)

{i++;

a[i]=1;

continue;

}//不到9个数,往后继续

while(a[i]==9&

i>

1)i--;

//往前回溯

if(a[i]==9&

i==1)break;

elsea[i]++;

//至第1个数为9结束

共以上%d个解。

递归程序实现:

//桥本分数式递归求解

inta[10],s=0;

{intput(intk);

put

(1);

//调用递归函数put

(1)

共有以上%d个解。

//桥本分数式递归函数

intput(intk)

{inti,j,u,m1,m2,m3;

if(k<

=9)

{for(i=1;

=9;

i++)//探索第k个数字取值i

{a[k]=i;

for(u=0,j=1;

=k-1;

j++)

if(a[k]==a[j])

u=1;

//出现重复数字,则置u=1

if(u==0)//若第k个数字可为i

{if(k==9&

a[4])//若已9个数字,则检查等式

{m1=a[2]*10+a[3];

if(a[1]*m2*m3+a[4]*m1*m3==a[7]*m1*m2)

{s++;

printf("

<

->

:

"

//输出一个解

%d/%d+%d/%d"

a[1],m1,a[4],m2);

=%d/%d"

a[7],m3);

elseput(k+1);

//若不到9个数字,则调用put(k+1)

returns;

3.给定有n个不同的正数组成的集合W={Wi|Wi>

0,i=1,2,…,n}和给定正数M,求出M中所有使其和数等于M的子集。

即给定一个n个整数的集合W={W1,W2....Wn}和整数M,找出和等于M的W的子集。

如:

W={11,13,24,7}M=31问题的解为:

{24,7}和{11,13,7}

解可以用布尔向量表示为:

{0,0,1,1},{1,1,0,1}

又如:

W={10,20,30,40,50,60}和M=60,则有三种不同长度的解,它们分别是{10,20,30},{20,40},{60}.这个问题可以用另一种方法明确表达,使得解是一种明显的长度为n的布尔向量,于是上面的三个解可以用布尔向量表示为:

{1,1,1,0,0,0},{0,1,0,1,0,0},{0,0,0,0,0,1}

 

conio.h>

#defineMAX1000

//globalvariables

intn=0;

//thenumberofnumbers

intc=0;

//thesumofthesubset

intnum[MAX]={0};

intcount=1;

//thenumberoftheelementinasubset

intresult[MAX]={0};

//theanswerofthisquestion

intc_sum=0;

//currentsum

//prototypes

voidswap(int&

a,int&

b);

voidback_subset(inti);

intmain()

{

//declaration

inti=0;

Pleaseinputthenumberofthenumbers:

scanf("

Pleaseinputthesum:

c);

for(i=1;

i++)

scanf("

num[i]);

back_subset

(1);

getch();

voidback_subset(inti)

if(c_sum+num[i]==c)

{

result[count]=num[i];

for(inttemp=1;

temp<

=count;

temp++)

printf("

%d"

result[temp]);

printf("

\n\n\n\n----------separateline------------------\n\n\n\n"

return;

}

if(i>

n)

if(c_sum+num[i]>

c)

return;

for(intj=i;

result[count++]=num[j];

c_sum+=num[j];

swap(num[i],num[j]);

back_subset(i+1);

c_sum-=num[j];

count--;

b)

inttemp=a;

a=b;

b=temp;

iostream>

usingnamespacestd;

constintMAX=11;

constintb[MAX]={1,2,3,4,5,8,11,23,45};

intx[MAX]={0};

intsum;

intSum();

intSumOfSub(int,int,int);

voidDisplay(int*);

intmain()

cout<

<

enterthesum:

endl;

cin>

>

sum;

ints=0,k=0,r;

r=Sum();

//cout<

r<

endl;

SumOfSub(s,k,r);

intSum()

ints=0;

for(inti=0;

i<

MAX;

s+=b[i];

intSumOfSub(ints,intk,intr)

if(r<

0)return0;

x[k]=1;

if(s+b[k]==sum)

Display(x);

if(s+b[k]+b[k+1]<

=sum)

SumOfSub(s+b[k],k+1,r-b[k]);

//if(s+r-b[k]>

=sum&

s+b[k+1]<

//{

x[k]=0;

SumOfSub(s,k+1,r-b[k]);

//}

voidDisplay(int*x)

if(x[i]==1)

cout<

b[i]<

\t"

;

这个算法应该不难,基本和全排列的算法类似,只不过判断条件不是n=1,而是在判断已经取得的数的和>

=M为终止条件。

具体的算法,我给个大概流程吧

intlst[N];

//保存选取的数

intindex=0;

//lst中最后的一个数的位置

func(W,N)

if(N==0)//遍历完毕返回

return;

for(i=0toN)

if(W[i][1]!

=-1)//判断是否已经读取当前值

lst[index++]=W[i][0]//当前值加入到保存数组

W[i][1]=-1;

//设置当前值已经读取,不可再读

if(check()==0)

func(W,N-1);

//大小不够M,继续往下读

elseif(check()==1)

print(lst);

//和为M,输出

lst[--index]=0;

//回溯,寻找下一组解

W[i][1]=0;

check()

if(sum(lst)>

W)

return-1;

if(sum(lst)<

return0;

return1;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 院校资料

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1