基本算法经典题目模板

基本算法经典题目模板
基本算法经典题目模板

一、动态规划:(几个经典的代码)1:最长不下降子序列

/*

// 最长不下降序列

F[j] 表示最长的个数

pre[j]。。。前驱标志

F[j]=max{ F[i]+1 | a[j]>a[i],1}(0

14

13 7 9 16 38 24 27 38 44 49 21 52 63 15 */

#include

#include

#define Max 100

using namespace std;

int pre[Max];// 记录前驱

int f[Max];// 记录结束点为j 的最大值stack s;

// 显然f[0]=0; f[1]=1;

int a[Max];

int max,max_t;// max 用于存放最大长的个数,max_t 用于存放最长个数的结尾标志点

void Long_up(int a[],int n){

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

for(int j=0;j

if(a[i]>=a[j]){

if(f[j]+1>f[i]){

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

if(f[i]>max){

max=f[i];

max_t=i;

}

pre[i]=j;

}

}

}

} }

int main(void){

int n;

cin>>n;

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

cin>>a[i];

}

Long_up(a,n);

cout<

cout<

s.push(max_t);

i=pre[max_t];

while(i!=0){

s.push(i);

i=pre[i];

}

while(!s.empty()){

cout<

s.pop();

}cout<

}

2、合并石子:

/*

把第i 个到第j 个石子合并的记录为f[i:j]

把从第i 到j 的石子的最大(或者最小)价值为max[i][j] 那么有f[i:j]=max{ f[i:k]+f[k+1:j]}其中i<=k

#include

#define Max 100

using namespace std;

int a[Max];

int p[Max][Max];//记录f[i:j]

int max[Max][Max];//

int s[Max][Max];// 记录为

void sovle_max(int n){//

memset(p,0,sizeof(p));

memset(max,0,sizeof(max));

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

p[i][i]=a[i];

}

for( int r=2;r<=n;r++){

for(int i=1;i<=n-r+1;i++){

int j=i+r-1;

int temp=0;

for(int k=i;k

if(p[i][k]+p[k+1][j]+max[i][k]+max[k+1] [j]>temp){

temp=p[i][k]+p[k+1][j]+max[i][k]+max[ k+1][j];

p[i][j]=p[i][k]+p[k+1][j];

s[i][j]=k;

}

}

//p[i][j]=temp;

max[i][j]=temp;

}

}

}

void sovle_min(int n){//

memset(p,0,sizeof(p));

memset(max,0,sizeof(max));

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

p[i][i]=a[i];

}

for( int r=2;r<=n;r++){

for(int i=1;i<=n-r+1;i++){

int j=i+r-1;

int temp=(1<<30);

for(int k=i;k

if(p[i][k]+p[k+1][j]+max[i][k]+max[k+1] [j]

temp=p[i][k]+p[k+1][j]+max[i][k]+max[ k+1][j];

p[i][j]=p[i][k]+p[k+1][j];

s[i][j]=k;

}

}

//p[i][j]=temp;

max[i][j]=temp;

}

}

}

void print(int n){

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

for(int j=1;j<=n;j++){

cout<

}

cout<

}

}

int main(void){

int n;

cin>>n;

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

cin>>a[i];

}

sovle_max(n);

print(n);

sovle_min(n);

print(n);

}

3、最大子段合问题:

/*

b[j]=max{ b[j-1]+a[j] , a[j] } 0

#include

using namespace std;

int Maxsum(int *a,int n){

int b=0,sum=0; // b 表示的是b[j] ,,,sum 表示的是最大和

for(int i=0;i

if(b>0)

b+=a[i];

else// 如果b<0 那么b+a < a 则b=a;

b=a[i];

if(b>sum){

sum=b;

}

}

return sum;

}

int main(void){

int a[]={-2,11,-4,13,-5,-2};

cout<

最大字段和问题的多维推广:

#include

#define Max 102

using namespace std;

int a[Max][Max];

// 最大的子序列

int Maxsum(int n,int *a,int &start,int &end){ int b=0,sum=0;

int x1=0,x2=0;

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

if(b>0){

b+=a[i];

x2++;

}

else{

b=a[i];

x1=i;

x2=i;

}

if(sum

sum=b;

start=x1;

end=x2;

}

}

//cout<"<

return sum;

}

// 求矩阵中的最大子矩阵使得和最大

int Maxsum_2(int m,int n,int a[][Max]){// m 行n 列的矩阵

int start_x, end_x;

int start_y,end_y;

int start_temp,end_temp;

int *b=new int[n+1];// 定义保存数组

int sum=0;

for(int i=1;i<=m;i++){ // 从第 1 行到第m 行一行为首行进行搜索

for(int k=1;k<=n;k++){// 对b[] 进行初始化

b[k]=0;

}

for( int j=i;j<=m;j++){// 从首行开

始对下面的行进行搜索确定最大值

for(int k=1;k<=n;k++){// 将第j 行的元素和第i 行的元素进行相加

b[k]+=a[j][k];

}

int

max=Maxsum(n,b,start_temp,end_temp); // 每一次选出和最大的序列

if(max>sum){

//

cout<"<

start_y=i;

end_y=j;

start_x=start_temp;

end_x=end_temp;

sum=max;

// cout<

}

}

}

// cout<"<"<

return sum;

}

int main(void){

int n;

cin>>n;

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

for(int j=1;j<=n;j++){

cin>>a[i][j];

}

}

cout<

return 0;

}

4、最长公共子序列:

#include

#include

#define Max 125

using namespace std;

void LCSLength(int m,int n,char *x,char*y,int **c){//

for(int i=1;i<=m;i++){

c[i][0]=0;

}

for(int j=1;j<=n;j++){

c[0][j]=0;

}

for(i=1;i<=m;i++){

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

if(x[i]==y[j]){

c[i][j]= c[i-1][j-1]+1;

}

else if(c[i-1][j]>c[i][j-1]){

c[i][j]=c[i-1][j];

}

else

c[i][j]=c[i][j-1];

}

}

/* for(i=1;i<=m;i++){

for(int j=1;j<=n;j++){

cout<

}

cout<

}*/

cout<

}

int main(void){

string x1,y1;

cin>>x1>>y1;

int m=0,n=0;

char x[Max],y[Max];

x[0]='0';y[0]='0';

m=x1.length();

n=y1.length();

for(int i=0;i

x[i+1]=x1[i];

} for(i=0;i

}

int **c;

c=new int*[m+1];

for(i=0;i<=m;i++){

c[i]=new int[n+1];

for(int j=0;j<=n;j++){

c[i][j]=0;

}

}

LCSLength(m, n,x,y,c);

}

5、矩阵连乘问题

#include

using namespace std;

void matrixchin(int *p,int **m,int **s,int n){ for(int i=1;i<=n;i++){

m[i][i]=0;

}

for(int temp=2;temp<=n;temp++){

for(int

row=1;row<=n-temp+1;row++){

int low=row+temp-1;

m[row][low]=m[row+1][low]+p[row-1]* p[row]*p[low];

s[row][low]=i;

for(int k=row+1;k

int

t=m[row][k]+m[k+1][low]+p[row-1]*p[k]*p[l ow];

if(t

m[row][low]=t;

s[row][low]=k;

}

}

}

}

}

int main(void){

int n;

int p[]={ 30,35,15,5,10,20,25};

int **m,**s;

cin>>n;

m=new int*[n+1];

s=new int*[n+1];

for(int i=0;i<=n;i++){

m[i]=new int[n+1];

s[i]=new int[n+1];

for(int j=0;j<=n;j++){

m[i][j]=0;

s[i][j]=0;

}

}

matrixchin(p, m,s, n);

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

for(int j=1;j<=n;j++){

cout<

}

cout<

}

return 0;

}

6、滑雪问题:备忘录法

#include

#define Max 200

using namespace std;

int map[Max][Max];

int re[Max][Max];

int d[4][2]={{0,-1},{-1,0},{0,1},{1,0}};

int flage[Max][Max];

int dfs(int x,int y,int m,int n){

if(re[x][y]!=0){

return re[x][y];

}

int re_max=0;// 表示四周的最大值

for(int i=0;i<4;i++){

int xt=x+d[i][0],yt=y+d[i][1];

if( xt<=0 || yt<=0 || xt>m || yt>n || flage[xt][yt]==1 || map[xt][yt]>=map[x][y]){

continue;

}

int temp=dfs(xt,yt,m,n);

if(temp>re_max){

re_max=temp;

}

}

return re[x][y]=re_max+1;

}

void solve(int m,int n){

for(int i=1;i<=m;i++){

for(int j=1;j<=n;j++){

dfs(i,j,m,n);

}

}

}

int main(void){

int max=0;

int m,n,i;

cin>>m>>n;

for(i=1;i<=m;i++){

for(int j=1;j<=n;j++){

cin>>map[i][j];

}

}

memset(re,0,sizeof(re));

solve(m,n);

for(i=1;i<=m;i++){

for(int j=1;j<=m;j++){

if(re[i][j]>max){

max=re[i][j];

}

}

}

cout<

}

二、贪心算法:(经典题目)

1、最短路径dijkstra 算法

#include

#define Max 100

using namespace std;

void dijkstra(int n,int v,int dis[],int prev[],int **c){

bool mark[Max]; //标记是否被使用true 为被使用,flase为没有被使用

for(int i=1;i<=n;i++){// 初始化

dis[i]=c[v][i];// dis[i] 为n 到i 的距离

mark[i]=false;//

if(dis[i]==Max){

prev[i]=0;

}

else{

prev[i]=v;

}

}

mark[v]=true;dis[v]=0;// 从v 开始

for(i=1;i

int u=v;

int temp=Max;

for(int j=1;j<=n;j++){// v 顶点从1~n 顶点开始搜索找到离u 最短的距离j

if(!mark[j] && dis[j]

temp=dis[j];

u=j;

}

}

mark[u]=true;// 将找到的u (标记起来)并加入搜索

for( j=1;j<=n;j++){// 修改距离。。

if(!mark[j] && c[u][j]

int newdis=dis[u]+c[u][j];

if(newdis

dis[j]=newdis;

prev[j]=u;

}

}

}

}

}

int main(void){

int n;

int **c;

int *dis;

int *prev;

int v;

cin>>n>>v;

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

prev=new int[n+1];

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

for(int i=0;i<=n;i++){

c[i]=(int*)malloc(sizeof(int )*(n+1));

dis[i]=0;

for(int j=0;j<=n;j++){

c[i][j]=Max;

}

}

while(v--){

cout<<"输入顶点x-> y = d的距离"<

int x,y;

cin>>x>>y;

cin>>c[x][y];

}

dijkstra( n, 1,dis, prev,c);

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

cout<

}

cout<

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

cout<

}

cout<

return 0;

}

2、求最小生成树的prime 算法

#include

#define Max 100

using namespace std;

void Prim(int n,int **c){

int lowcost[Max];

int closet[Max];// closet[i] 表示的i 顶点的前驱^^

bool s[Max];// 标记是否使用

s[1]=true;// 从第一个顶点开始

for(int i=1;i<=n;i++){// 初始化,lowcost[i] 表示的是从的1 个顶点到个个顶点的距离

lowcost[i]=c[1][i];

closet[i]=1;// loset[i]

s[i]=false;// 设置成没有被访问(初始化)

}

for(i=1;i

int min=Max;

int j=1;// j 表示的是当前开始搜索最短边的顶点

for(int k=2;k<=n;k++){ // 开始搜索与j 相连最短的边的顶点

if((lowcost[k]

min=lowcost[k];

j=k;

}

}

cout<

s[j]=true;//标记已近被使用

for( k=2;k<=n;k++)

if((c[j][k]

lowcost[k]=c[j][k];

closet[k]=j;

}

}

}int main(void){

int n,e;

int **c;

cin>>n>>e;

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

for(int i=0;i<=n;i++){

c[i]=(int

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

for(int j=0;j<=n;j++){

c[i][j]=Max;

}

}

while(e--){

cout<<"输入顶点x-> y = d的距离"<

int x,y;

cin>>x>>y;

cin>>c[x][y];

c[y][x]=c[x][y];

}

Prim( n, c);

return 0;

}

次小生成树:

#include

#define Max 105

#define inf 999999

using namespace std;

int q[Max-1][2];

int prim(int n,int **c){

int i,k;

int sum=0;

int lowcost[Max];

int closet[Max];// closet[i] 表示的i 顶点的前驱^^

bool s[Max];// 标记是否使用

s[1]=true;// 从第一个顶点开始

for( i=2;i<=n;i++){// 初始化,lowcost[i] 表示的是从的1 个顶点到个个顶点的距离lowcost[i]=c[1][i];

closet[i]=1;// loset[i]

s[i]=false;// 设置成没有被访问(初始化)

}

for(i=1;i

int min=inf;

int j=1;// j 表示的是当前开始搜索最短边的顶点

for(k=2;k<=n;k++){ // 开始搜索与j 相连最短的边的顶点

if((lowcost[k]

min=lowcost[k];

j=k;

}

}

//cout<

s[j]=true;//标记已近被使用

sum+=min;

q[i][0]=closet[j];q[i][1]=j;

for( k=2;k<=n;k++)

if((c[j][k]

小于从开始的

lowcost[k]=c[j][k];

closet[k]=j;

}

}

return sum;

}

int prim_1(int n,int **c){

int i,k;

int sum=0;

int lowcost[Max];

int closet[Max];// closet[i] 表示的i 顶点的前驱^^

bool s[Max];// 标记是否使用

s[1]=true;// 从第一个顶点开始

for( i=1;i<=n;i++){// 初始化,lowcost[i] 表示的是从的1 个顶点到个个顶点的距离lowcost[i]=c[1][i];

closet[i]=1;// loset[i]

s[i]=false;// 设置成没有被访问(初始化)

}

for(i=1;i

int min=inf;

int j=1;// j 表示的是当前开始搜索最短边的顶点

for(k=2;k<=n;k++){ // 开始搜索与j 相连最短的边的顶点

if((lowcost[k]

min=lowcost[k];

j=k;

}

}

s[j]=true;//标记已近被使用

sum+=min;

for( k=2;k<=n;k++)

if((c[j][k]

lowcost[k]=c[j][k];

closet[k]=j;

}

}

return sum;

}

int prime_cixiao(int n,int **c){

int min=inf;

for(int i=1;i

int x=q[i][0];int y=q[i][1];

// cout<"<

int dis=c[x][y];

c[x][y]=inf;

c[y][x]=inf;

int temp=prim_1( n,c);

if(temp

min=temp;

}

c[x][y]=dis;

c[y][x]=dis;

}

return min;

}

int main(void){

int t;

cin>>t;

while(t--){

int n,e;

cin>>n>>e;

int **c;

c=new int*[n+1];

for(int i=0;i<=n;i++){

c[i]=new int[n+1];

for(int j=0;j<=n;j++){

c[i][j]=inf;

}

}

while(e--){

int a,b,v;

cin>>a>>b>>v;

c[a][b]=v;

c[b][a]=v;

}

memset(q,0,sizeof(q));

int sum=prim( n,c);

//cout<

int temp=prime_cixiao(n,c);

if(sum==temp){

cout<<"Not Unique!"<

}else{

cout<

}

free(c);

}

return 0;

}

三、回溯法(经典例题)

1、n 皇后问题

2、求幂集

#include

using namespace std;

int *result;

int vise[4];

void solve_power_set(int a[],int start,int n){// 求幂集

if(start>n){

for(int j=1;j<=n;j++){

if(result[j]!=0){

cout<

}

else{

//cout<<" ";

}

}

cout<

return ;

}

if(result[start-1]<=0){

result[start]=0;

solve_power_set(a, start+1,n);

}

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

if(vise[i]==0 && a[i]>result[start-1]){

result[start]=a[i];

vise[i]=1;

solve_power_set(a, start+1,n);

vise[i]=0;

}

}

} void rangment(int a[],int n,int start){ if(start>n){

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

cout<

}

cout<

return ;

}

for(int j=1;j<=n;j++){

if(vise[j]==0){

result[start]=a[j];

vise[j]=1;

rangment(a,n,start+1);

vise[j]=0;

}

}

}

int main(void){

result=new int[4];

int a[]={0,1,2,3};

// solve_power_set(a, 1,3);

rangment(a,3,1);

}

3、作业调度问题

#include

#include

#define N 3//作业数目

#define MAX 1000

int x[N+1]={0,1,2,3};// x[] 表示所有作业

int m[3][N+1]={ // m[i][j];表示作业在机器i 上,第j 个作业所需要的时间

0,0,0,0,

0,2,3,2,

0,1,1,3

};

int bestx[N+1]; //用于保存结果调度顺序int f2[N+1]; //第i阶段机器2完成处理的时间

int f1=0; //机器1完成处理时间

int f=0; //当前完成时间和

int bestf=MAX;

void swap(int &a,int &b)

{

int temp=a;

a=b;

b=temp;

}

void Backtrace(int t)// t 表是完成作业t {

if(t>N)// 所有的作业已近完成

{

bestf=f;

for(int i=1;i<=N;i++)

{

bestx[i]=x[i];

printf("%d ",bestx[i]);

}

printf("\n");

}

else

{

for(int i=t;i<=N;i++)

{

f1+=m[1][x[i]];

f2[t]=(f2[t-1]>f1?f2[t-1]:f1)+m[2][x[i]];

f+=f2[t];

swap(x[t],x[i]);

if(f

{

Backtrace(t+1);

}

swap(x[t],x[i]);

f1-=m[1][x[i]];

f-=f2[t];

}

}

}

int main()

{

memset(bestx,0,(N+1)*sizeof(int));

memset(f2,0,(N+1)*sizeof(int));

Backtrace(1);

printf("该作业调度的最优完成时间和为:%d\n调度顺序为:\n",bestf);

for(int i=1;i<=N;i++)

{

printf("%d ",bestx[i]);

}

return 0;

}

4、装箱问题

/*

*/

#include

using namespace std;

int bestw,cw;// bestw 为装的最好重量, r 为剩余的重量,cw 为当前装载的重量

int x[100];// 标记第i 个物品是否选择

int y[100];

void loading(int w[],int n,int c,int i,int r){// a[] 为个个物品的重量,w 为能装的最大的重量,n 为物品的个数,i 表示对第i 个物品进行判断;

if(i>=n){ // 到达了木末尾bestw 为当前的最好的

for(int i=0;i

y[i]=x[i];

}

bestw=cw;

return ;

}

r-=w[i];

if(cw+w[i]<=c){

x[i]=1; // 选择第i 物品

cw+=w[i];

loading(w, n, c, i+1,r);

cw-=w[i];

}

if(cw+r>bestw){

x[i]=0;

loading(w, n, c, i+1,r);

}

r+=w[i];

} int main(void){

int w[100];

int n,c,r=0;

cin>>n>>c;

for(int i=0;i

cin>>w[i];

r+=w[i];

}

loading(w, n,c, 0,r);

cout<

for( i=0;i

cout<

}

cout<

return 0;

}

分治法:

1、快速排序

#include

using namespace std;

int stor(int a[],int p,int r) {

int x=a[p];

int i=p;int j=r+1;

while(true)

{

while(a[i++]

;

while(a[--j]>x )

;

if(i>j) break;

else

{

int temp=0;

temp=a[i];

a[i]=a[j];

a[j]=a[i];

}

}

temp=a[p];

a[p]=a[j];

a[j]=tmp;

}

int main(void)

{

int a[10];

for(int i=0;i<=0;i++)

{

cin>>a[i];

}

}

数学建模_BP神经网络算法模板

1.1 BP 神经网络原理简介 BP 神经网络是一种多层前馈神经网络,由输入、输出、隐藏层组成。该网络的主要特点是信号前向传递,误差反向传播。在前向传递中,输入信号从输入层经隐藏层逐层处理,直至输出层。每一层的神经元状态只影响下一层神经元状态。如果输出层得不到期望输出则转入反向传播,根据预测误差调整网络权值和阈值,从而使BP 神经网络预测输出不断逼近期望输出。结构图如下: 隐藏层传输函数选择Sigmoid 函数(也可以选择值域在(-1,1)的双曲正切函数,函数‘tansig ’),其数学表达式如下: x e 11)x ( f α-+=,其中α为常数 输出层传输函数选择线性函数:x )x (f = 1.隐藏层节点的选择 隐藏层神经元个数对BP 神经网络预测精度有显著的影响,如果隐藏层节点数目太少,则网络从样本中获取信息的能力不足,网络容易陷入局部极小值,有时可能训练不出来;如果隐藏层节点数目太多,则学习样本的非规律性信息会出现“过度吻合”的现象,从而导致学习时间延长,误差也不一定最佳,为此我们参照以下经验公式: 12+=I H ]10,1[ ,∈++=a a O I H I H 2log = 其中H 为隐含层节点数,I 为输入层节点数,O 为输出层节点数,a 为常数。 输入层和输出层节点的确定: 2.输入层节点和输出层节点的选择 输入层是外界信号与BP 神经网络衔接的纽带。其节点数取决于数据源的维数和输入特征向量的维数。选择特征向量时,要考虑是否能完全描述事物的本质特征,如果特征向量不能有效地表达这些特征,网络经训练后的输出可能与实际有较大的差异。因此在网络训练前,应全面收集被仿真系统的样本特性数据,并在数据处理时进行必要的相关性分析,剔除那些边沿和不可靠的数据,最终确定出数据源特征向量的维度。对于输出层节点的数目,往往需要根据实际应用情况灵活地制定。当BP 神经网络用于模式识别时,模式的自身特性就决定了输出的结果数。当网络作为一个分类器时,输出层节点数等于所需信息类别数。(可有可无) 训练好的BP 神经网络还只能输出归一化后的浓度数据,为了得到真实的数据

算法设计及分析递归算法典型例题

算法递归典型例题 实验一:递归策略运用练习 三、实验项目 1.运用递归策略设计算法实现下述题目的求解过程。 题目列表如下: (1)运动会开了N天,一共发出金牌M枚。第一天发金牌1枚加剩下的七分之一枚,第二天发金牌2枚加剩下的七分之一枚,第3天发金牌3枚加剩下的七分之一枚,以后每天都照此办理。到了第N天刚好还有金牌N枚,到此金牌全部发完。编程求N和M。 (2)国王分财产。某国王临终前给儿子们分财产。他把财产分为若干份,然后给第一个儿子一份,再加上剩余财产的1/10;给第二个儿子两份,再加上剩余财产的1/10;……;给第i 个儿子i份,再加上剩余财产的1/10。每个儿子都窃窃自喜。以为得到了父王的偏爱,孰不知国王是“一碗水端平”的。请用程序回答,老国王共有几个儿子?财产共分成了多少份? 源程序: (3)出售金鱼问题:第一次卖出全部金鱼的一半加二分之一条金鱼;第二次卖出乘余金鱼的三分之一加三分之一条金鱼;第三次卖出剩余金鱼的四分之一加四分之一条金鱼;第四次卖出剩余金鱼的五分之一加五分之一条金鱼;现在还剩下11条金鱼,在出售金鱼时不能把金鱼切开或者有任何破损的。问这鱼缸里原有多少条金鱼? (4)某路公共汽车,总共有八站,从一号站发轩时车上已有n位乘客,到了第二站先下一半乘客,再上来了六位乘客;到了第三站也先下一半乘客,再上来了五位乘客,以后每到一站都先下车上已有的一半乘客,再上来了乘客比前一站少一个……,到了终点站车上还有乘客六人,问发车时车上的乘客有多少? (5)猴子吃桃。有一群猴子摘来了一批桃子,猴王规定每天只准吃一半加一只(即第二天吃剩下的一半加一只,以此类推),第九天正好吃完,问猴子们摘来了多少桃子? (6)小华读书。第一天读了全书的一半加二页,第二天读了剩下的一半加二页,以后天天如此……,第六天读完了最后的三页,问全书有多少页? (7)日本著名数学游戏专家中村义作教授提出这样一个问题:父亲将2520个桔子分给六个儿子。分完后父亲说:“老大将分给你的桔子的1/8给老二;老二拿到后连同原先的桔子分1/7给老三;老三拿到后连同原先的桔子分1/6给老四;老四拿到后连同原先的桔子分1/5给老五;老五拿到后连同原先的桔子分1/4给老六;老六拿到后连同原先的桔子分1/3给老大”。结果大家手中的桔子正好一样多。问六兄弟原来手中各有多少桔子? 四、实验过程 (一)题目一:…… 1.题目分析 由已知可得,运动会最后一天剩余的金牌数gold等于运动会举行的天数由此可倒推每一 天的金牌剩余数,且每天的金牌数应为6的倍数。 2.算法构造 设运动会举行了N天, If(i==N)Gold[i]=N; Else gold[i]=gold[i+1]*7/6+i;

矩阵算法经典题目

经典题目 这里我们不介绍其它有关矩阵的知识,只介绍矩阵乘法和相关性质。 不要以为数学中的矩阵也是黑色屏幕上不断变化的绿色字符。在数学中,一个矩阵说穿了就是一个二维数组。一个n行m列的矩阵可以乘以一个m行p列的矩阵,得到的结果是一个n行p列的矩阵,其中的第i行第j列位置上的数等于前一个矩阵第i行上的m个数与后一个矩阵第j列上的m个数对应相乘后所有m个乘积的和。比如,下面的算式表示一个2行2列的矩阵乘以2行3列的矩阵,其结果是一个2行3列的矩阵。其中,结果的那个4等于2*2+0*1: 右面的算式则是一个1 x 3的矩阵乘以3 x 2的矩阵,得到一个1 x 2的矩阵: 矩阵乘法的两个重要性质:一,矩阵乘法不满足交换律;二,矩阵乘法满足结合律。为什么矩阵乘法不满足交换律呢?因为交换后两个矩阵有可能不能相乘。为什么它又满足结合律呢?假设你有三个矩阵A、B、C,那么(AB)C和 A(BC)的结果的第i行第j列上的数都等于所有A(ik)*B(kl)*C(lj)的和(枚举所有的k和l)。 经典题目1 给定n个点,m个操作,构造O(m+n)的算法输出m个操作后各点的位置。操作有平移、缩放、翻转和旋转这里的操作是对所有点同时进行的。其中翻转是以坐标轴为对称轴进行翻转(两种情况),旋转则以原点为中心。如果对每个点分别进行模拟,那么m个操作总共耗时O(mn)。利用矩阵乘法可以在O(m)的时间里把所有操作合并为一个矩阵,然后每个点与该矩阵相乘即可直接得出最终该点的位置,总共耗时O(m+n)。假设初始时某个点的坐标为x和y,下面5个矩阵可以分别对其进行平移、旋转、翻转和旋转操作。预先把所有m个操作所对应的矩阵全部乘起来,再乘以(x,y,1),即可一步得出最终点的位置。 经典题目2 给定矩阵A,请快速计算出A^n(n个A相乘)的结果,输出的每个数都mod p。 由于矩阵乘法具有结合律,因此A^4 = A * A * A * A = (A*A) * (A*A) = A^2 * A^2。我们可以得到这样的结论:当n 为偶数时,A^n = A^(n/2) * A^(n/2);当n为奇数时,A^n = A^(n/2) * A^(n/2) * A (其中n/2取整)。这就告诉我们,计算A^n也可以使用二分快速求幂的方法。例如,为了算出A^25的值,我们只需要递归地计算出A^12、A^6、A^3的值即可。根据这里的一些结果,我们可以在计算过程中不断取模,避免高精度运算。 经典题目3 POJ3233 (感谢rmq) 题目大意:给定矩阵A,求A + A^2 + A^3 + ... + A^k的结果(两个矩阵相加就是对应位置分别相加)。输出的数据mod m。k<=10^9。 这道题两次二分,相当经典。首先我们知道,A^i可以二分求出。然后我们需要对整个题目的数据规模k进行二分。比如,当k=6时,有: A + A^2 + A^3 + A^4 + A^5 + A^6 =(A + A^2 + A^3) + A^3*(A + A^2 + A^3) 应用这个式子后,规模k减小了一半。我们二分求出A^3后再递归地计算A + A^2 + A^3,即可得到原问题的答案。

常用算法模板库(C++)

1 排序算法 1.1 冒泡排序 /* 函数功能:对数组中的某一部分进行冒泡排序。 函数原形:void BubSort(DataType a[], int l, int r, bool Up=true); 参数: DataType a[]:欲排序的数组; int l:有序序列在数组中的起始位置; int r:有序序列在数组中的结束位置; bool Up:true按升序排列,false按降序排列。 返回值:无。 备注:无。 */ template void BubSort(DataType a[], int l, int r, bool Up=true) { int i,j; DataType k; if (Up) { for (i=l;i<=r-1;i++) for (j=r;j>=i+1;j--) if (a[j-1]>a[j]) { k=a[j-1]; a[j-1]=a[j]; a[j]=k; } } else for (i=l;i<=r-1;i++) for (j=r;j>=i+1;j--) if (a[j-1] void SelectSort(DataType a[], int l, int r, bool Up=true) { int i,j; DataType k; if (Up) { for (i=l;i<=r-1;i++) for (j=i+1;j<=r;j++) if (a[i]>a[j]) { k=a[i]; a[i]=a[j]; a[j]=k; }

计算机算法设计与分析期末考试复习题

1、二分搜索算法是利用( A )实现的算法。 A、分治策略 B、动态规划法 C、贪心法 D、回溯法 2、下列不是动态规划算法基本步骤的是( A )。 A、找出最优解的性质 B、构造最优解 C、算出最优解 D、定义最优解 3、最大效益优先是( A )的一搜索方式。 A、分支界限法 B、动态规划法 C、贪心法 D、回溯法 4、最长公共子序列算法利用的算法是( B )。 A、分支界限法 B、动态规划法 C、贪心法 D、回溯法 5. 回溯法解TSP问题时的解空间树是( A )。 A、子集树 B、排列树 C、深度优先生成树 D、广度优先生成树6.下列算法中通常以自底向上的方式求解最优解的是( B )。 A、备忘录法 B、动态规划法 C、贪心法 D、回溯法 7、衡量一个算法好坏的标准是(C )。 A 运行速度快 B 占用空间少 C 时间复杂度低 D 代码短 8、以下不可以使用分治法求解的是(D )。 A 棋盘覆盖问题 B 选择问题 C 归并排序 D 0/1背包问题 9. 实现循环赛日程表利用的算法是( A )。 A、分治策略 B、动态规划法 C、贪心法 D、回溯法 10、实现最长公共子序列利用的算法是( B )。 A、分治策略 B、动态规划法 C、贪心法 D、回溯法11.下面不是分支界限法搜索方式的是( D )。 A、广度优先 B、最小耗费优先 C、最大效益优先 D、深度优先 12.下列算法中通常以深度优先方式系统搜索问题解的是( D )。 A、备忘录法 B、动态规划法 C、贪心法 D、回溯法 13. 一个问题可用动态规划算法或贪心算法求解的关键特征是问题的( B )。 A、重叠子问题 B、最优子结构性质 C、贪心选择性质 D、定义最优解14.广度优先是( A )的一搜索方式。 A、分支界限法 B、动态规划法 C、贪心法 D、回溯法 15.背包问题的贪心算法所需的计算时间为( B )。

算法设计与分析考试题及答案

1.一个算法就是一个有穷规则的集合,其中之规则规定了解决某一特殊类型问题的一系列运算,此外,算法还应具有以下五个重要特性:_________,________,________,__________,__________。 2.算法的复杂性有_____________和___________之分,衡量一个算法 好坏的标准是______________________。 3.某一问题可用动态规划算法求解的显着特征是 ____________________________________。 4.若序列X={B,C,A,D,B,C,D},Y={A,C,B,A,B,D,C,D},请给出序列X 和Y的一个最长公共子序列_____________________________。 5.用回溯法解问题时,应明确定义问题的解空间,问题的解空间至少应包含___________。 6.动态规划算法的基本思想是将待求解问题分解成若干____________,先求解___________,然后从这些____________的解得到原问题的解。 7.以深度优先方式系统搜索问题解的算法称为_____________。 背包问题的回溯算法所需的计算时间为_____________,用动态规划算法所需的计算时间为____________。 9.动态规划算法的两个基本要素是___________和___________。? 10.二分搜索算法是利用_______________实现的算法。 二、综合题(50分) 1.写出设计动态规划算法的主要步骤。 2.流水作业调度问题的johnson算法的思想。

矩阵典型习题解析

2 矩阵 矩阵是学好线性代数这门课程的基础,而对于初学者来讲,对于矩阵的理解是尤为的重要;许多学生在最初的学习过程中感觉矩阵很难,这也是因为对矩阵所表示的内涵模糊的缘故。其实当我们把矩阵与我们的实际生产经济活动相联系的时候,我们才会发现,原来用矩阵来表示这些“繁琐”的事物来是多么的奇妙!于是当我们对矩阵产生无比的兴奋时,那么一切问题都会变得那么的简单! 2.1 知识要点解析 2.1.1 矩阵的概念 1.矩阵的定义 由m×n 个数),,2,1;,,2,1(n j m i a ij 组成的m 行n 列的矩形数表 mn m m n n a a a a a a a a a A 21 22221 11211 称为m×n 矩阵,记为n m ij a A )( 2.特殊矩阵 (1)方阵:行数与列数相等的矩阵; (2)上(下)三角阵:主对角线以下(上)的元素全为零的方阵称为上(下) 三角阵; (3)对角阵:主对角线以外的元素全为零的方阵; (4)数量矩阵:主对角线上元素相同的对角阵; (5)单位矩阵:主对角线上元素全是1的对角阵,记为E ; (6)零矩阵:元素全为零的矩阵。 3.矩阵的相等 设mn ij mn ij b B a A )(; )( 若 ),,2,1;,,2,1(n j m i b a ij ij ,则称A 与B 相等,记为A=B 。 2.1.2 矩阵的运算

1.加法 (1)定义:设mn ij mn ij b B A A )(,)( ,则mn ij ij b a B A C )( (2)运算规律 ① A+B=B+A ; ②(A+B )+C =A +(B+C ) ③ A+O=A ④ A +(-A )=0, –A 是A 的负矩阵 2.数与矩阵的乘法 (1)定义:设,)(mn ij a A k 为常数,则mn ij ka kA )( (2)运算规律 ① K (A+B ) =KA+KB , ② (K+L )A =KA+LA , ③ (KL ) A = K (LA ) 3.矩阵的乘法 (1)定义:设.)(,)(np ij mn ij b B a A 则 ,)(mp ij C C AB 其中 n k kj ik ij b a C 1 (2)运算规律 ①)()(BC A C AB ;②AC AB C B A )( ③CA BA A C B )( (3)方阵的幂 ①定义:A n ij a )( ,则K k A A A ②运算规律:n m n m A A A ;mn n m A A )( (4)矩阵乘法与幂运算与数的运算不同之处。 ①BA AB ②;00,0 B A AB 或不能推出 ③k k k B A AB )( 4.矩阵的转置 (1)定义:设矩阵A =mn ij a )(,将A 的行与列的元素位置交换,称为矩阵A 的转置,记为nm a A ji T )( , (2)运算规律 ①;)(A A T T ②T T T B A B A )(; ③;)(T T KA kA ④T T T A B AB )(。

软件开发报价和报价材料模板的计算方法

软件开发报价的计算方法 1.软件开发价格估算方法 软件开发价格与工作量、商务成本、国家税收和企业利润等项有关。为了便于计算,给出一个计算公式: 软件开发价格=开发工作量× 开发费用/人·月 1.1开发工作量 软件开发工作量与估算工作量经验值、风险系数和复用系数等项有关:软件开发工作量=估算工作量经验值× 风险系数× 复用系数 1.1.1估算工作量经验值(以A来表示) 软什开发工作量的计算,曾有人提出以源代码行或功能点来计算,这些方法实施起来均有不少难度。目前国际上仍旧按以往经验的方式加以计算,国内各软件企业也是采用经验的方式加以估算工作量。 1.1.2风险系数(以σ来表示) 估算工作量经验值亦会存在较大风险,造成软件危机的因素很多,这也是一个方面的因素。特别当软件企业对该信息工程项目的业务领域不熟悉或不太熟悉,而且用户又无法或不能完整明白地表达他们的真实的需求,从而造成软件企业需要不断地完善需求获取,修改设计等各项工作。因此: l ≤ 风险系数≤ 1.5 根据我们对软件企业的了解,超过估算工作量经验值的一半,已是不可接受,所以我们确定“1.5”为极限值。当然这既要看企业的能力,也要看用户能接受的程度。 1.1.3复用系数(以τ来表示) 估算工作量经验值是软件企业承担一般项目来估算的,但如果软件企业已经采用“基于构件的开发方法” ,并己建立起能够复用的构件库(核心资产库),或者已有一些软件产品,仅作二次开发,从而使软件开发工作量减少。因此: 0.25 ≤ 复用系数≤ 1 根据国内外软件企业在实施基于构件开发方法(软件产品线)的经验数据,提高工作效率达到25%(最高值)。 1.2开发费用/人·月 软件企业的商务成本、国家税收、企业利润、管理成本和质量成本。均可摊分到各个软件开发人员头上。 开发费用/人·月=(P+Q+R)× S× τ 1.2.1 P(人头费) 人头费主要是员工的工资、奖金和国家规定的各项按人计算的费用。其总量在软件企业中的商务成本占70%-80%。 P = B × 1.476 国家规定的公积金 7%,医疗保险金12%,养老金22%,失业金 2%(即通常所说的四金),另外还有按工资总额计征的工伤保证金0.5%,生育保证金0.5%,残疾基金1.6%,工会基金2%,累计为47.6%。 B为平均工资,即企业支付给员工的工资、奖金、物质奖励等多项总和,除以企业员工数,分摊到每个月。

算法设计与分析

算法设计与分析实验报告 姓名:888 学号:129074999 老师:许精明

实验1:杨辉三角 解法思路: 根据杨辉三角中除最外层(不包括杨辉三角底边)的数为1外,其余的数都是它肩上两个数之和这一性质,用数组输出杨辉三角。 根据杨辉三角的第n行恰好是C(n,0)~C(n,n),可以不用数组输出,而用动态规划。这里的C表示组合。 注:由于为了便于控制输出格式,程序中的最大输出行确定的较小,但程序本身并没有错误。若要输出更多行,需要增加控制输出格式的语句。 解法一:数组 #include void print(int *row,int n) { int i; for(i=1;i

分块矩阵乘法的例子

分块矩阵乘法的例子 例 1 用分块法计算,AB 其中 00 51 2414 21,5 31001200 2 0-???? ? ?== ? ? ? ?-? ?? ? A B . 解 B A,如上分块, ???? ??=2221 1211 A A A A A , ??? ? ??=2322 21 131211 B B B B B B B , 其中 111221224 21(0,0),(5), ,,0 12????==== ? ?-?? ?? A A A A ()()()0,20,0,01,1342,51232221131211===??? ? ??-=???? ??=???? ??=B B B B B B ; 令==C AB ??? ? ??232221 131211 C C C C C C ,其中 =+=2112111111B A B A C )0()0)(5(51)00(=+??? ? ??, =+=2212121112B A B A C )00(()()()1002051342=+???? ??, =+=2312131113B A B A C )0()0)(5(01)00(=+???? ??-, =+=2122112121B A B A C ??? ? ??-=???? ??+???? ?????? ??-514)0(21511024, =+=2222122122B A B A C ???? ??-=???? ??+???? ?????? ??-332014)20(2113421024, =+=2322132123B A B A C ??? ? ??-=???? ??+???? ??-???? ??-04)0(21011024.

《算法分析与设计》期末试题及参考答案

《算法分析与设计》期末试题及参考答案 一、简要回答下列问题: 1.算法重要特性是什么? 1.确定性、可行性、输入、输出、有穷性 2. 2.算法分析的目的是什么? 2.分析算法占用计算机资源的情况,对算法做出比较和评价,设计出额更好的算法。 3. 3.算法的时间复杂性与问题的什么因素相关? 3. 算法的时间复杂性与问题的规模相关,是问题大小n的函数。 4.算法的渐进时间复杂性的含义? 4.当问题的规模n趋向无穷大时,影响算法效率的重要因素是T(n)的数量级,而其他因素仅是使时间复杂度相差常数倍,因此可以用T(n)的数量级(阶)评价算法。时间复杂度T(n)的数量级(阶)称为渐进时间复杂性。 5.最坏情况下的时间复杂性和平均时间复杂性有什么不同? 5. 最坏情况下的时间复杂性和平均时间复杂性考察的是n固定时,不同输入实例下的 算法所耗时间。最坏情况下的时间复杂性取的输入实例中最大的时间复杂度: W(n) = max{ T(n,I) } , I∈Dn 平均时间复杂性是所有输入实例的处理时间与各自概率的乘积和: A(n) =∑P(I)T(n,I) I∈Dn 6.简述二分检索(折半查找)算法的基本过程。 6. 设输入是一个按非降次序排列的元素表A[i:j] 和x,选取A[(i+j)/2]与x比较, 如果A[(i+j)/2]=x,则返回(i+j)/2,如果A[(i+j)/2]

算法设计与分析学习总结

算法分析与设计 学习总结 题目:算法分析与设计学习总结 学院信息科学与工程学院专业2013级计算机应用技术 届次 学生姓名 学号2013110657 二○一三年一月十五日

算法分析与设计学习总结 本学期通过学习算法分析与设计课程,了解到:算法是一系列解决问题的清晰指令,代表着用系统的方法描述解决问题的策略机制。算法能够对一定规范的输入,在有限时间内获得所要求的输出。如果一个算法有缺陷,或不适合某个问题,执行这个算法将不会解决这个问题。不同的算法可能用不同的时间、空间或效率来完成同样的任务。一个算法的优劣可以用空间复杂性和时间复杂度来衡量。算法可以使用自然语言、伪代码、流程图等多种不同的方法来描述。计算机系统中的操作系统、语言编译系统、数据库管理系统以及各种各样的计算机应用系统中的软件,都必须使用具体的算法来实现。算法设计与分析是计算机科学与技术的一个核心问题。 设计的算法要具有以下的特征才能有效的完成设计要求,算法的特征有:(1)有穷性。算法在执行有限步后必须终止。(2)确定性。算法的每一个步骤必须有确切的定义。(3)输入。一个算法有0个或多个输入,作为算法开始执行前的初始值,或初始状态。(4)输出。一个算法有一个或多个输出,以反映对输入数据加工后的结果。没有输出的算法是毫无意义的。 (5)可行性。在有限时间内完成计算过程。 算法设计的整个过程,可以包含对问题需求的说明、数学模型的拟制、算法的详细设计、算法的正确性验证、算法的实现、算法分析、程序测试和文档资料的编制。算法可大致分为基本算法、数据结构的算法、数论与代数算法、计算几何的算法、图论的算法、动态规划以及数值分析、加密算法、排序算法、检索算法和并行算法。 经典的算法主要有: 1、穷举搜索法 穷举搜索法是对可能是解的众多候选解按某种顺序进行逐一枚举和检验,bing从中找出那些符合要求的候选解作为问题的解。 穷举算法特点是算法简单,但运行时所花费的时间量大。有些问题所列举书来的情况数目会大得惊人,就是用高速计算机运行,其等待运行结果的时间也将使人无法忍受。我们在用穷举算法解决问题是,应尽可能将明显不符合条件的情况排除在外,以尽快取得问题的解。 2、迭代算法 迭代法是数值分析中通过从一个初始估计出发寻找一系列近似解来解决问题(一般是解方程或方程组)的过程,为实现这一过程所使用的方法统称为迭代法。迭代法是用于求方程或方程组近似根的一种常用的算法设计方法。设方程为f(x)=0,用某种数学方法导出等价的形式x=g(x),然后按以下步骤执行: (1)选一个方程的近似根,赋给变量x0。 (2)将x0的值保存于变量x1,然后计算g(x1),并将结果存于变量x0。 (3)当x0与x1的差的绝对值还小于指定的精度要求时,重复步骤(2)的计算。 若方程有根,并且用上述方法计算出来的近似根序列收敛,则按上述方法求得的x0就认为是方程的根。 3、递推算法 递推算法是利用问题本身所具有的一种递推关系求问题解的一种方法。它把问题分成若干步,找出相邻几步的关系,从而达到目的。 4、递归算法 递归算法是一种直接或间接的调用自身的算法。 能采用递归描述的算法通常有这样的特征:为求解规模为n的问题,设法将它分解成规模较小的问题,然后从这些小问题的解方便地构造出大问题的解,并且这些规模较小的问题也能采用同样的分解和综合方法,分解成规模更小的问题,并从这些更小问题的解构造出规模

《算法分析与设计》期末复习题

一、选择题 1.一个.java文件中可以有()个public类。 A.一个B.两个C.多个D.零个 2.一个算法应该是() A.程序B.问题求解步骤的描述 C.要满足五个基本特性D.A和C 3.用计算机无法解决“打印所有素数”的问题,其原因是解决该问题的算法违背了算法特征中的()A.唯一性B.有穷性C.有0个或多个输入D.有输出 4.某校有6位学生参加学生会主席竞选,得票数依次为130,20,98,15,67,3。若采用冒泡排序算法对其进行排序,则完成第二遍时的结果是() A.3,15,130,20,98,67B.3,15,20,130,98,67 C.3,15,20,67,130,98 D.3,15,20,67,98,130 5.下列关于算法的描述,正确的是() A.一个算法的执行步骤可以是无限的B.一个完整的算法必须有输出 C.算法只能用流程图表示D.一个完整的算法至少有一个输入 6.Java Application源程序的主类是指包含有()方法的类。 A、main方法 B、toString方法 C、init方法 D、actionPerfromed方法 7.找出满足各位数字之和等于5的所有三位数可采用的算法思路是() A.分治法B.减治法C.蛮力法D.变治法 8.在编写Java Application程序时,若需要使用到标准输入输出语句,必须在程序的开头写上( )语句。 A、import java.awt.* ; B、import java.applet.Applet ; C、import java.io.* ; D、import java.awt.Graphics ; 9.计算某球队平均年龄的部分算法流程图如图所示,其中:c用来记录已输入球员的人数,sum用来计算有效数据之和,d用来存储从键盘输入的球员年龄值,输入0时表示输入结束。

算法设计与分析基础习题参考答案

习题1.1 5..证明等式gcd(m,n)=gcd(n,m mod n)对每一对正整数m,n都成立. Hint: 根据除法的定义不难证明: 如果d整除u和v, 那么d一定能整除u±v; 如果d整除u,那么d也能够整除u的任何整数倍ku. 对于任意一对正整数m,n,若d能整除m和n,那么d一定能整除n和r=m mod n=m-qn;显然,若d 能整除n和r,也一定能整除m=r+qn和n。 数对(m,n)和(n,r)具有相同的公约数的有限非空集,其中也包括了最大公约数。故gcd(m,n)=gcd(n,r) 6.对于第一个数小于第二个数的一对数字,欧几里得算法将会如何处理?该算法在处理这种输入的过程中,上述情况最多会发生几次? Hint: 对于任何形如0<=m

可达矩阵快速算法

传递闭包Warshall方法计算可达矩阵简要介绍 ①在集合X上的二元关系R的传递闭包是包含R的X上的最小的传递关系。R的传递闭包在数字图像处理的图像和视觉基础、图的连通性描述等方面都是基本概念。一般用B表示定义在具有n个元素的集合X上关系R的n×n二值矩阵,则传递闭包的矩阵B+可如下计算: B+ = B + B2 + B3 + ……+ (B)n ②式中矩阵运算时所有乘法都用逻辑与代替,所有加法都用逻辑或代替。上式中的操作次序为B,B(B),B(BB),B(BBB),……,所以在运算的每一步我们只需简单地把现有结果乘以B,完成矩阵的n次乘法即可。 https://www.360docs.net/doc/ab2793469.html, /ism/cal_warshall_get_r_mat_detail.php Warshall在1962年提出了一个求关系的传递闭包的有效算法。 其具体过程如下,设在n个元素的有限集上关系R的关系矩阵为M:(1)置新矩阵A=M; (2)置k=1; (3)对所有i如果A[i,k]=1,则对j=1..n执行: A[i,j]←A[i,j]∨A[k,j];

(4)k增1; (5)如果k≤n,则转到步骤(3),否则停止。 所得的矩阵A即为关系R的传递闭包t(R)的关系矩阵。 在《离散数学》中都提及了该算法。 Warshall算法映射到有向图中 设关系R的关系图为G,设图G的所有顶点为u1,u2,…,un,则t(R)的关系图可用该方法得到:若G中任意两顶点ui和uj之间有一条路径且没有ui到uj的弧,则在图G中增加一条从ui到uj的弧,将这样改造后的图记为G’,则G’即为t(R)的关系图。G’的邻接矩阵A应满足:若图G中存在从ui到uj路径,即ui与uj连通,则A[i,j]=1,否则 A[i,j]=0。 这样,求t(R)的问题就变为求图G中每一对顶点间是否连通的问题。 相乘矩阵,就为所有节点的关系图,也就是当前条件下的关系矩阵。 对于相乘矩阵,进行叠代,叠代的过程为,行取值,然后计算值中对应的每一行的值取并集,得到当前行的关系集合。 取完所有行,得到了一个新的转移矩阵再对转移矩阵进行进行求解。

第二章 矩阵及其运算测试题

第二章 矩阵及其运算测试题 一、选择题 1.下列关于矩阵乘法交换性的结论中错误的是( )。 (A)若A 是可逆阵,则1A -与1A -可交换; (B)可逆矩阵必与初等矩阵可交换; (C)任一n 阶矩阵与n cE 的乘法可交换,这里c 是常数; (D)初等矩阵与初等矩阵的乘法未必可交换。 2.设n (2n ≥)阶矩阵A 与B 等价,则必有( ) (A) 当A a =(0a ≠)时,B a =; (B)当A a =(0a ≠)时,B a =-; (C) 当0A ≠时,0B =; (D)当0A =时,0B =。 3.设A 、B 为方阵,分块对角阵00A C B ??= ??? ,则* C =( )。 (A) **00 A B ?? ??? (B) **||00 ||A A B B ?? ??? (C) **||00||B A A B ?? ??? (D) **||||0 0||||A B A A B B ?? ??? 4.设A 、B 是n (2n ≥)阶方阵,则必有( )。 (A)A B A B +=+ (B)kA k A = (C) A A B B =-g (D) AB A B = 5.设4阶方阵 44(),()||,ij A a f x xE A ?==-其中E 是4阶单位矩阵,则()f x 中3 x 的系数为( )。 (A)11223344()a a a a -+++ (B)112233112244223344113344a a a a a a a a a a a a +++ (C) 11223344a a a a (D)11223344a a a a +++ 6.设A 、B 、A B +、11A B --+均为n 阶可逆矩阵,则1()A B -+为( )。 (A) 11A B --+ (B) A B + (C) 111()A B ---+ (D)11111 ()B A B A -----+

矩阵乘法题目

十个利用矩阵乘法解决的经典题目 By Matrix67 好像目前还没有这方面题目的总结。这几天连续看到四个问这类题目的人,今天在这里简单写一下。这里我们不介绍其它有关矩阵的知识,只介绍矩阵乘法和相关性质。 不要以为数学中的矩阵也是黑色屏幕上不断变化的绿色字符。在数学中,一个矩阵说穿了就是一个二维数组。一个n行m列的矩阵可以乘以一个m行p列的矩阵,得到的结果是一个n行p列的矩阵,其中的第i行第j列位置上的数等于前一个矩阵第i行上的m个数与后一个矩阵第j列上的m个数对应相乘后所有m个乘积的和。比如,下面的算式表示一个2行2列的矩阵乘以2行3列的矩阵,其结果是一个2行3列的矩阵。其中,结果的那个4等于2*2+0*1:下面的算式则是一个1 x 3的矩阵乘以3 x 2的矩阵,得到一个1 x 2的矩阵:矩阵乘法的两个重要性质:一,矩阵乘法不满足交换律;二,矩阵乘法满足结合律。为什么矩阵乘法不满足交换律呢?废话,交换过来后两个矩阵有可能根本不能相乘。为什么它又满足结合律呢?仔细想想你会发现这也是废话。假设你有三个矩阵A、B、C,那么(AB)C和A(BC)的结果的第i行第j列上的数都等于所有A(ik)*B(kl)*C(lj)的和(枚举所有的k和l)。 经典题目1 给定n个点,m个操作,构造O(m+n)的算法输出m个操作后各点的位置。操作有平移、缩放、翻转和旋转 这里的操作是对所有点同时进行的。其中翻转是以坐标轴为对称轴进行翻转(两种情况),旋转则以原点为中心。如果对每个点分别进行模拟,那么m个操作总共耗时O(mn)。利用矩阵乘法可以在O(m)的时间里把所有操作合并为一个矩阵,然后每个点与该矩阵相乘即可直接得出最终该点的位置,总共耗时 O(m+n)。假设初始时某个点的坐标为x和y,下面5个矩阵可以分别对其进行平移、旋转、翻转和旋转操作。预先把所有m个操作所对应的矩阵全部乘起来,再乘以(x,y,1),即可一步得出最终点的位置。 经典题目2 给定矩阵A,请快速计算出A^n(n个A相乘)的结果,输出的每个数都mod p。 由于矩阵乘法具有结合律,因此A^4 = A * A * A * A = (A*A) * (A*A) = A^2 * A^2。我们可以得到这样的结论:当n为偶数时,A^n = A^(n/2) * A^(n/2);当n为奇数时,A^n = A^(n/2) * A^(n/2) * A (其中n/2取整)。这就告诉我们,计算A^n也可以使用二分快速求幂的方法。例如,为了算出A^25的值,我们只需要递归地计算出A^12、A^6、A^3的值即可。根据这里的一些结果,我们可以在计算过程中不断取模,避免高精度运算。 经典题目3 POJ3233 (感谢rmq) 题目大意:给定矩阵A,求A + A^2 + A^3 + ... + A^k的结果(两个矩阵相加就是对应位置分别相加)。输出的数据mod m。k<=10^9。 这道题两次二分,相当经典。首先我们知道,A^i可以二分求出。然后我们需要对整个题目的数据规模k进行二分。比如,当k=6时,有: A + A^2 + A^3 + A^4 + A^5 + A^6 =(A + A^2 + A^3) + A^3*(A + A^2 + A^3) 应用这个式子后,规模k减小了一半。我们二分求出A^3后再递归地计算A + A^2 + A^3,即可得到原问题的答案。

算法分析与设计期末考试试卷b卷

西南交通大学2015-2016学年第(一)学期考试试卷 课程代码 3244152 课程名称 算法分析与设计 考试时间 120 分钟 阅卷教师签字: 一、 填空题(每空1分,共15分) 1、 程序是 (1) 用某种程序设计语言的具体实现。 2、 矩阵连乘问题的算法可由 (2) 设计实现。 3、 从分治法的一般设计模式可以看出,用它设计出的程序一般是 (3) 。 4、 大整数乘积算法是用 (4) 来设计的。 5、 贪心算法总是做出在当前看来 (5) 的选择。也就是说贪心算法并不从整体最优考虑,它所做出的选择只是在某种意义上的 (6) 。 6、 回溯法是一种既带有 (7) 又带有 (8) 的搜索算法。 7、 平衡二叉树对于查找算法而言是一种变治策略,属于变治思想中的 (9) 类型。 8、 在忽略常数因子的情况下,O 、Ω和Θ三个符号中, (10) 提供了算法运行时间的一个上界。 9、 算法的“确定性”指的是组成算法的每条 (11) 是清晰的,无歧义的。 10、 问题的 (12) 是该问题可用动态规划算法或贪心算法求解的关键特征。 11、 算法就是一组有穷 (13) ,它们规定了解决某一特定类型问题的 (14) 。 12、 变治思想有三种主要的类型:实例化简,改变表现, (15) 。 二、 选择题(每题2分,共20分) 1、 二分搜索算法是利用( )实现的算法。 A 、分治策略 B 、动态规划法 C 、贪心法 D 、回溯法 2、 衡量一个算法好坏的标准是( )。 A 、运行速度快 B 、占用空间少 C 、 时间复杂度低 D 、代码短 3、 能采用贪心算法求最优解的问题,一般具有的重要性质为:( ) A. 最优子结构性质与贪心选择性质 B .重叠子问题性质与贪心选择性质 C .最优子结构性质与重叠子问题性质 D. 预排序与递归调用 4、 常见的两种分支限界法为( ) 班 级 学 号 姓 名 密封装订线 密封装订线 密封装订线

算法与流程图模板

算法与流程图

§13.1 算法与流程图 1. 以下对算法的描述正确的有 个. ①对一类问题都有效; ②算法可执行的步骤必须是有限的; ③计算能够一步步地进行, 每一步都有确切的含义; ④是一种通法, 只要按部就班地做, 总能得到结果. 答案 4 2.任何一个算法都必须有的基本结构是 . 答案 顺序结构 3.下列问题的算法适宜用选择结构表示的是 ( 填序号) . ①求点P( -1, 3) 到直线l:3x-2y+1=0的距离 ②由直角三角形的两条直角边求斜边 ③解不等式ax+b >0 (a ≠0) ④计算100个数的平均数 答案 ③ 4.下列4种框图结构中, 是直到型循环结构的为 ( 填序号) . 基础自测

答案② 5.( ·广东理, 9) 阅读下面的流程图, 若输入m=4, n=3, 则输出a= , i= .( 注: 框图中的赋值符号”←”也能够写成”=” 或”: =”) 答案12 3 例1已知点P( x0, y0) 和直线l:Ax+By+C=0, 求点P( x0, y0) 到直线l 的距离d, 写出其算法并画出 流程图. 解算法如下: 第一步, 输入x0,y0及直线方程的系数A, B, C.

流程图: 第二步, 计算Z 1←Ax 0+By 0+C. 第三步, 计算Z 2←A 2+B 2. 第四步, 计算d ←2 1Z Z . 第五步, 输出d. 例2 ”特快专递”是当前人们经常使用的异地邮寄信函或托运物品的一种快捷方式, 某快递公司规定甲、 乙两地之间物品的托运费用根据下列方法计算: f =? ? ?>?-+?≤)100(85 .0)100(6.0100) 100(6.0ωωωω 其中f(单位: 元)为托运费,ω为托运物品的重量( 单位: 千克) .试设计计算费用f 的算法, 并画出流程图. 解 算法如下: S1 输入ω; S2 如果ω≤100,那么f ←0.6ω; 否则 f ←100×0.6+(ω-100)×0.85; S3 输出f. 流程图为: 例3 ( 14分) 画出计算12-22+32-42+…+992-1002的值的流程图. 解 流程图如下图.

相关文档
最新文档