算法实验报告.docx

上传人:b****7 文档编号:10637196 上传时间:2023-02-22 格式:DOCX 页数:22 大小:82.28KB
下载 相关 举报
算法实验报告.docx_第1页
第1页 / 共22页
算法实验报告.docx_第2页
第2页 / 共22页
算法实验报告.docx_第3页
第3页 / 共22页
算法实验报告.docx_第4页
第4页 / 共22页
算法实验报告.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

算法实验报告.docx

《算法实验报告.docx》由会员分享,可在线阅读,更多相关《算法实验报告.docx(22页珍藏版)》请在冰豆网上搜索。

算法实验报告.docx

算法实验报告

算法实验报告

 

实验一:

一、实验目的与要求

熟悉C/C++语言的集成开发环境;

通过本实验加深对分治法、贪心算法的理解。

二、实验内容:

掌握分治法、贪心算法的概念和基本思想,并结合具体的问题学习如何用相应策略进行求解的方法。

三、实验题

1.【伪造硬币问题】给你一个装有n个硬币的袋子。

n个硬币中有一个是伪造的。

你的任务是找出这个伪造的硬币。

为了帮助你完成这一任务,将提供一台可用来比较两组硬币重量的仪器,利用这台仪器,可以知道两组硬币的重量是否相同。

试用分治法的思想写出解决问题的算法,并计算其时间复杂度。

2.【找零钱问题】一个小孩买了价值为33美分的糖,并将1美元的钱交给售货员。

售货员希望用数目最少的硬币找给小孩。

假设提供了数目有限的面值为25美分、10美分、5美分、及1美分的硬币。

给出一种找零钱的贪心算法。

四、实验程序

1.伪造硬币问题源程序

#include

#include

#include

usingnamespacestd;

intweight(int,int);

#definesize1000

inta[size];

intmain()

{inti,n;

intt,f,k;

intm;

time_tts;

srand((unsigned)time(&ts));

cout<<"请输入硬币个数"<

cin>>n;

cout<<"请输入真币和伪造硬币的重量"<

cin>>t>>f;

for(i=0;i

a[size]=0;

for(i=0;i

a[i]=t;

k=rand()%n;//随机产生假硬币的下标

a[k]=f;

cout<<"随机产生的伪造硬币的位置"<

cout<

cout<<"随机产生的硬币排列顺序"<

for(i=0;i

{

cout<

if((i+1)%20==0)

cout<

}

cout<

m=weight(0,n-1);

if(m==-1)

cout<<"没有伪造硬币"<

else

cout<<"伪造硬币的位置是"<

cout<

return0;

}

//称重函数m,n分别为数组的最小及最大下标,每次把硬币等分三堆

intweight(intm,intn){

intj=0;

inti=0;

intsum1=0;

intsum2=0;

intsum3=0;

if(m>=n)

return-1;

for(i=0;i<(n-m+1)/3;i++,j++)

{

sum1+=(a[m+j]);

sum2+=(a[m+(n-m+1)/3+j]);

sum3+=(a[m+2*(n-m+1)/3+j]);

}

//数组元素个数除三余一的情况

if(((n-m+1)%3)==1)

{

if(sum1==sum2)

{

if(sum1==sum3)

{

if(a[n]==a[n-1])

return-1;

else

returnn;

}

else

{

m=m+2*((n-m+1)/3);

weight(m,n);

}

}

else

if(sum1==sum3)

{

m=m+(n-m+1)/3;

n=m+2*((n-m+1)/3)-1;

weight(m,n);

}

else

{

n=m+(n-m+1)/3-1;

weight(m,n);

}

}

//数组元素个数除三余二的情况

else

if(((n-m+1)%3)==2)

{

if(sum1==sum2)

{

if(sum1==sum3)

{

if(a[n]==a[n-2])

{

if(a[n-1]==a[n-2])

return-1;

else

returnn-1;

}

else

returnn;

}

else

{

m=m+2*((n-m+1)/3);

weight(m,n);

}

}

else

if(sum1==sum3)

{

m=m+(n-m+1)/3;

n=m+2*((n-m+1)/3)-1;

weight(m,n);

}

else

{

n=m+(n-m+1)/3-1;

weight(m,n);

}

}

//数组元素个数被三整除的情况

else

if(sum1==sum2)

{

if(sum1==sum3)

{

return-1;

}

else

{

m=m+2*((n-m+1)/3);

weight(m,n);

}

}

else

{

if(sum1==sum3)

{

m=m+(n-m+1)/3;

n=m+2*((n-m+1)/3)-1;

weight(m,n);

}

else

{

n=m+(n-m+1)/3-1;

weight(m,n);

}

}

}

实验结果

2.找零钱问题

源程序如下:

#include

intmain()

{

intmoney,value,returns;

inttwenty_five,ten,five,one;

inti,j,k,l;

i=0;

j=0;

k=0;

l=0;

money=100;

value=33;

returns=money-value;

cout<<"***应该找给孩子的钱是(美分):

"<

cout<<"***请输入现有的25美分,10美分,5美分,1美分硬币的个数***"<

cin>>twenty_five>>ten>>five>>one;

i=returns/25;

if(i<=twenty_five)

returns-=25*i;

else

{

returns-=twenty_five*25;

i=twenty_five;

}

if(returns>0)

{

j=returns/10;

if(j<=ten)

returns-=10*j;

else

{

returns-=ten*10;

j=ten;

}

}

if(returns>0)

{

k=returns/5;

if(k<=five)

returns-=5*k;

else

{

returns-=five*5;

k=five;

}

}

if(returns>0)

{

l=returns;

if(l<=one)

returns-=l;

else

{

returns-=one;

l=one;

}

}

if((returns=returns-(i*25+j*10+k*5+l))>0)

cout<<"不好意思,现在没有足够的硬币!

"<

else

{

cout<<"***应找25美分的个数是:

"<

cout<<"***应找10美分的个数是:

"<

cout<<"***应找5美分的个数是:

"<

cout<<"***应找1美分的个数是:

"<

}

return0;

}

实验结果:

实验二:

一、实验目的与要求

熟悉C/C++语言的集成开发环境;

通过本实验加深对贪心算法、动态规划和回溯算法的理解。

二、实验内容:

掌握贪心算法、动态规划和回溯算法的概念和基本思想,分析并掌握"0-1"背包问题的三种算法,并分析其优缺点。

三、实验题

1."0-1"背包问题的贪心算法

2."0-1"背包问题的动态规划算法

3."0-1"背包问题的回溯算法

四.1

"0-1"背包问题的贪心算法源程序:

#include

#include

usingnamespacestd;

structgood//表示物品的结构体

{

doublep;//价值

doublew;//重量

doubler;//价值与重量的比

}a[200];

doubles,value,m,result;

inti,n;

boolbigger(gooda,goodb)

{

returna.r>b.r;

}

intmain()

{

printf("----------背包问题之贪心算法------------------\n");

printf("输入物品个数:

");

scanf("%d",&n);//物品个数

printf("输入物品的重量和价值:

");

for(i=0;i

{

scanf("%lf%lf",&a[i].w,&a[i].p);

a[i].r=a[i].p/a[i].w;

}

sort(a,a+n,bigger);//调用sort排序函数,你大概不介意吧,按照价值与重量比排序贪心

printf("输入背包的容量;");

scanf("%lf",&m);//读入包的容量m

s=0;//包内现存货品的重量

value=0;//包内现存货品总价值

result=0;

for(i=0;i

{value+=a[i].p;

s+=a[i].w;}

result=value*s;

printf("背包内物品总价值为:

%.2lf.\n",result);//输出结果

return0;

}

运行结果:

2

"0-1"背包问题的动态规划算法源程序

#include

#include

#include

#include

usingnamespacestd;

voidKnapsack(vectorvct_v,vectorvct_w,intc,intn);

voidprint(vectorv);

voidprintarr(vector>m,intp,intq);

voidTraceback(vector>m,vectorvct_w,intc,intn);

voidmain()

{

intmo=10;

vectorvct_w;

vectorvct_v;

intc,n,v,w;

cout<<"***0-1背包问题之动态规划***"<

cout<<"***请输入物品个数***"<

cin>>n;

srand((unsigned)time(NULL));

vct_w.push_back(n);//第一个位置存放物品个数

for(inti=1;i<=n;i++)

{

w=rand()%mo+1;

vct_w.push_back(w);

}

vct_v.push_back(n);

for(i=1;i<=n;i++)

{

v=rand()%mo+10;

vct_v.push_back(v);

}

cout<<"***请输入背包容量***"<

cin>>c;

cout<<"***请输入物品重量***"<

print(vct_w);

cout<<"***请输入物品价值***"<

print(vct_v);

Knapsack(vct_v,vct_w,c,n);

}

voidprint(vectorv)

{

for(inti=1;i

{

cout<

}

cout<

}

voidprintarr(vector>m,intp,intq)

{

for(inti=1;i<=p;i++)

{

for(intj=1;j<=q;j++)

{

cout<

}

cout<

}

cout<

}

voidKnapsack(vectorvct_v,vectorvct_w,intc,intn)

{

vector>m(n+1,vector(c+1));

intjMax;

for(inti=0;i<=n;i++)//为每一行分配空间

jMax=vct_w[n]-1

vct_w[n]-1:

c;

for(intj=0;j<=jMax;j++)

m[n][j]=0;

for(j=vct_w[n];j<=c;j++)

m[n][j]=vct_v[n];

for(i=n-1;i>1;i--)

{

intjMax=vct_w[i]-1

vct_w[i]-1:

c;

for(intj=0;j<=jMax;j++)

m[i][j]=m[i+1][j];

for(j=vct_w[i];j<=c;j++)

m[i][j]=m[i+1][j]>m[i+1][j-vct_w[i]]+vct_v[i]?

m[i+1][j]:

m[i+1][j-vct_w[i]]+vct_v[i];

}

m[1][c]=m[2][c];

if(c>=vct_w[1])

m[1][c]=m[1][c]>m[2][c-vct_w[1]]+vct_v[1]?

m[1][c]:

m[2][c-vct_w[1]]+vct_v[1];

cout<<"***m列表内容***"<

printarr(m,n,c);

Traceback(m,vct_w,c,n);

}

voidTraceback(vector>m,vectorvct_w,intc,intn)

{

vectorx;

x.push_back(0);

for(inti=1;i

{

if(m[i][c]==m[i+1][c])

x.push_back(0);

else

{x.push_back

(1);

c-=vct_w[i];

}

}

x.push_back((m[n][c])>0?

1:

0);

cout<<"***动态规划所得的最优解为***"<

for(i=1;i

{

cout<

}

cout<

}

运行结果:

3

"0-1"背包问题的回溯算法源程序

#include

#include

#include

intmin(intw,intc)

{inttemp;

if(w

else

temp=c;

returntemp;

}

intmax(intw,intc)

{

inttemp;

if(w>c)temp=w;

else

temp=c;

returntemp;

}

voidknapsack(intv[],intw[],intc,intn,int**m)//求最优值

{

intjmax=min(w[n]-1,c);

for(intj=0;j<=jmax;j++)

m[n][j]=0;

for(intjj=w[n];jj<=c;jj++)

m[n][jj]=v[n];

for(inti=n-1;i>1;i--){//递归部分

jmax=min(w[i]-1,c);

for(intj=0;j<=jmax;j++)

m[i][j]=m[i+1][j];

for(intjj=w[i];jj<=c;jj++)

m[i][jj]=max(m[i+1][jj],m[i+1][jj-w[i]]+v[i]);

}

m[1][c]=m[2][c];

if(c>=w[1])

m[1][c]=max(m[1][c],m[2][c-w[1]]+v[1]);

cout<<"最优值:

"<

for(intl=2;l<=n;l++)

for(intj=0;j<=c;j++)

{

cout<

}

cout<

cout<<"*******************************************"<

}

inttraceback(int**m,intw[],intc,intn,intx[])//回代,求最优解

{

cout<<"得到的一组最优解如下:

"<

for(inti=1;i

if(m[i][c]==m[i+1][c])x[i]=0;

else{x[i]=1;

c-=w[i];}

x[n]=(m[n][c])?

1:

0;

for(inty=1;y<=n;y++)

{

cout<

}

returnx[n];

}

main()

{

intn,c;

int**m;

cout<<"------------------0-1背包问题之回溯--------------------"<

cout<<"请输入物品个数和重量上限:

";

cin>>n>>c;

int*v=newint[n+1];

cout<<"输入各物品价值(v[i]):

"<

for(inti=1;i<=n;i++)

cin>>v[i];

int*w=newint[n+1];

cout<<"输入各物品重量(w[i]):

"<

for(intj=1;j<=n;j++)

cin>>w[j];

int*x=newint[n+1];

m=newint*[n+1];//动态的分配二维数组

for(intp=0;p

{

m[p]=newint[c+1];

}

knapsack(v,w,c,n,m);

traceback(m,w,c,n,x);

}

运行结果:

部分:

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

当前位置:首页 > 幼儿教育 > 唐诗宋词

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

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