最小重量机器设计
/*******************************/
#include<iostream>
#include<fstream>
#include<iomanip>
using namespace std;
class Machineshop{
friend int Machine(int **,int **,int,int,int,int []);
private:
void Backtrack(int t);
int **w; //各供应商的部件的重量
int **c; //各供应商的部件的价格
int *x; //当前设计方案
int *bestx; //当前最优设计方案
int cc; //当前价格
int cw; //当前重量
int bestw; //当前最小重量
int n; //部件数
int m; //供应商数
int d; //价格最大预算
};
void Machineshop::Backtrack(int i){//搜索第i层结点
///
if(i>n){ //到达叶结点
for(int j=1;j<=n;j++)
bestx[j]=x[j]; //当前最优设计方案
bestw=cw; //当前最优(小)重量
}
else
for(int j=1;j<=m;j++){
x[i]=j;
cw+=w[i][j];
cc+=c[i][j];
if(cc<=d && cw<bestw) //总价格不超过d,而且当前重量小于当前最优重量
Backtrack(i+1);
cw-=w[i][j];
cc-=c[i][j];
}
///
}
int Machine(int **w,int **c,int n,int m,int d,int bestx[]){
Machineshop X; //初始化X
X.x=new int[n+1];
X.m=m;
X.n=n;
X.d=d;
X.w=w;
X.c=c;
X.cc=0;
X.cw=0;
X.bestx=bestx;
X.bestw=32767;
for(int i=1;i<=n;i++)
X.x[i]=0;
X.Backtrack(1);
return X.bestw;
}
int main(){
int **w,**c,*bestx,n,m,d,i,j,f;
ifstream inFile("input.txt");
if(!inFile)
{
cerr<<"Can not open file."<<endl; //cerr 标准错误输出流
exit(1);
}
inFile>>n>>m>>d;
w=new int *[n+1];
for(i=1;i<=n;i++)
w[i]=new int[m+1];
for(i=1;i<=n;i++)
for(j=1;j<=m;j++){
inFile>>w[i][j];
}
c=new int *[n+1];
for(i=1;i<=n;i++)
c[i]=new int[m+1];
for(i=1;i<=n;i++)
for(j=1;j<=m;j++){
inFile>>c[i][j];
}
bestx=new int[n+1];
for(i=1;i<=n;i++)
bestx[i]=0;
f=Machine(w, c, n, m, d, bestx);
cout<<"最佳设计方案:"<<endl;
for(i=1;i<=n;i++)
cout<<"第"<<i<<"个零件选用第"<<bestx[i]<<"个销售商"<<endl;
cout<<"最小重量:"<<f<<endl;
}
工作分配问题:
/*******************************/
#include<iostream>
#include<fstream>
#include<iomanip>
using namespace std;
class Jobassignment{
friend int Job(int **,int,int []);
private:
void Backtrack(int t);
int **c; //c[i][j]为第i个工作分配给第j个工人所需的费用
int *x; //当前分配方案
int *bestx; //当前最优分配方案
int cc; //当前费用
int bestc; //当前最小总费用
int n; //工作数(也是工人数)
};
void Swap(int &a,int &b)
{
if(a!=b){
int temp=a;a=b;b=temp;
}
}
void Jobassignment::Backtrack(int i){//搜索第i层结点
if(i>n){ //到达叶结点
for(int j=1;j<=n;j++)
bestx[j]=x[j]; //当前最优分配方案
bestc=cc; //当前最优(小)费用
}
else
for(int j=i;j<=n;j++){
Swap(x[i],x[j]);
cc+=c[i][x[i]]; //加上工作i分配给第x[i]个工人需要的费用
if(cc<bestc)
Backtrack(i+1);
cc-=c[i][x[i]];
Swap(x[i],x[j]);
}
}
int Job(int **c,int n,int bestx[]){
Jobassignment X; //初始化X
X.x=new int[n+1];
X.n=n;
X.c=c;
X.cc=0;
X.bestx=bestx;
X.bestc=32767;
for(int i=1;i<=n;i++)
X.x[i]=i; //初始化解向量为1,2,3,...,n
X.Backtrack(1);
return X.bestc;
}
int main(){
int **c,*bestx,n,i,j,bestc;
ifstream inFile("input.txt");
if(!inFile)
{
cerr<<"Can not open file."<<endl; //cerr 标准错误输出流
exit(1);
}
inFile>>n;
c=new int *[n+1];
for(i=1;i<=n;i++) {
c[i]=new int[n+1];
for(j=1;j<=n;j++)
inFile>>c[i][j];
}
bestx=new int[n+1];
for(i=1;i<=n;i++)
bestx[i]=0;
bestc=Job(c, n, bestx);
cout<<"最佳分配方案:"<<endl;
for(i=1;i<=n;i++)
cout<<"第"<<i<<"个工作选用第"<<bestx[i]<<"个工人"<<endl;
cout<<"最小总费用:"<<bestc<<endl;
}
多处最优服务次序:
#include <iostream>
using namespace std;
float service(int *people,int n,int s)
{
int *m;
int temp;
int i,j,a,sum=0;
m=new int[s];
for(i=0;i<n;i++){
for(j=n-1;j>i;j--){
if(people[j]<people[j-1]){
temp=people[j];
people[j]=people[j-1];
people[j-1]=temp;
}
}
}
for(i=0;i<s;i++)m[i]=0; //初始化服务处空闲时间
for(j=0;j<n;j++){ //安排n位顾客
a=0;
for(i=1;i<s;i++)if(m[a]>m[i])a=i; //找目前空闲时间最早的服务处a
m[a]+=people[j];
sum+=m[a];
}
/*上面部分等价于
a=0
for(j=0;j<n;j++){
m[a]+=people[j];
sum+=m[a];
a++;
if(a==s) a=0
}*/ //无需再查找空闲时间最早的服务处,按顺序使用即可
return sum*1.0/n;
}
int main()
{
int *people;
int n;
int s;
cout<<"请输入顾客人数:";
cin>>n;
people=new int[n];
cout<<"请输入提供服务的场地数:";
cin>>s;
cout<<"请输入各个顾客服务的时间("<<n<<"个数):";
for(int i=0;i<n;i++)cin>>people[i];
cout<<"最小平均等待时间:"<<service(people,n,s)<<endl<<endl;
return 0;
}
汽车加油:
/*
汽车从初始地点出发,向目的地行进,中间有K个加油站,加满油能行驶距离为n(千米)。
从文件第一行读入n 和k的值,文件第二行是k+1段路每段的距离。求最少的加油次数。
*/
#include<iostream>
#include<fstream>
#include<stdlib.h>
#include<iomanip>
using namespace std;
int main()
{
int n=0;
int k=0;
int distAfterRefuel=0;
bool isRefuel=false;
int refuelCounter=0;
ifstream inFile1;
inFile1.open("input.txt",ios::in);
if(!inFile1)
{
cerr<<"Can not open file."<<endl; //cerr 标准错误输出流
exit(1);
}
inFile1>>n>>k;
int * distanceArray;
distanceArray=new int[k+1];
if(!distanceArray)
{
cerr<<"malloc failed."<<endl;
exit(1);
}
cout<<"每次加完油可行驶\t"<<n<<"km"<<endl;
cout<<"加油站个数:\t"<<k<<endl;
for(int i=0;i<k+1;i++)
{
inFile1>>distanceArray[i];
//distancearray[i]指从i站到i+1站的间距,distancearray[0]指从出发点到第1个加油站的间距
if(distanceArray[i]>n)
{
cout<<"no solution!"<<endl;
return 0;
}
}
distAfterRefuel=distanceArray[0];
for(int i=1;i<=k;i++)
{
if(distAfterRefuel==n||distAfterRefuel+distanceArray[i]>n)
//油刚好用完,或油没有用完,但剩下的油不够跑到下一站,则需要在第i站加油
{
cout<<" 在站点"<<i<<"加油"<<endl;
refuelCounter++;
distAfterRefuel=0; //加油后里程重新从0计
}
else //可以前行到下一站
{ cout<<" 在站点"<<i<<"不加油"<<endl;
}
distAfterRefuel+=distanceArray[i];//行驶至下一站
}
cout<<"总加油次数: "<<refuelCounter<<endl;
ofstream outFile("output.txt",ios::out);
outFile<<refuelCounter;
delete[] distanceArray;
return 0;
}
有重复元素的全排列:
#include <iostream>
using namespace std;
template<class Type>
int ch(Type list[],int k,int i)
{
if(i>k)
for(int t=k;t<i;t++)
if(list[t]==list[i])
return 0;
return 1;
}
template<class Type>
void perm(Type list[],int k,int m)
{
if (k==m)
{
for (int i=0;i<=m;i++)
cout<<list[i]; cout<<endl;
}
else
{
for(int i=k;i<=m;i++)
if(ch(list,k,i))
{
swap(list[k],list[i]);
perm(list,k+1,m);
swap(list[k],list[i]);
}
}
}
template<class Type>
inline void swap(Type &a,Type &b)
{
Type temp=a;a=b;b=temp;
}
int main()
{
int list[3]={1,2,3};
perm(list,0,2);
return 0;
}
租用游艇代码(改编自矩阵连乘):
#include<iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define z 4 //数组z行z列,站点个数=z-1
using namespace std;
void Traceback(int i,int j,int**s)
{
if(i+1==j || j==s[i][j]) //边界条件:在j站换船
{
cout<<"换船站"<<j<<endl;
return;
}
Traceback(i,s[i][j],s);
Traceback(s[i][j],j,s);
}
void MatrixChain(int n,int **m,int **s)
{
for (int r = 3; r <= n; r++) //r=2(两个站)时,m[i][i+1]的最优值就是初始值r[i][i+1],无需参与计算
for (int i = 1; i <= n - r+1; i++)
{
int j=i+r-1;
for (int k = i+1; k < j; k++) //换船位置从i+1到j-1(位置j已经在赋初值时用过了)
{
int t = m[i][k] + m[k][j] ;
if (t < m[i][j])
{
m[i][j] = t; s[i][j] = k;
}
}
}
}
void Print(int**m,int r,int c)
{
for(int i=1;i<=r;i++)
{
for(int j=1;j<=c;j++)
{
if(i>j)
cout<<"\t"; // 横向跳到下一制表位置
else
cout<<m[i][j]<<"\t";
}
cout<<endl<<endl;
}
}
int main()
{
int r[z][z]=
/* 实例1 */ //z=4时,3个站, 注意开始处设置z的值
{{0,0,0,0},
{0,0,5,15},
{0,0,0,7},
{0,0,0,0}};
/* 实例2 //z=5,4个站, 注意在开始处更改z的值
{{0,0,0,0,0},
{0,0,5,16,25},
{0,0,0,10,12},
{0,0,0,0,7},
{0,0,0,0,0}}; */
/* 实例3 //z=6,5个站, 注意在开始处更改z的值
{{0,0,0,0,0,0},
{0,0,5,8,10,20},
{0,0,0,4,8,12},
{0,0,0,0,3,6},
{0,0,0,0,0,2},
{0,0,0,0,0,0}}; */
int **m = new int * [z];
for(int i = 1; i < z; i ++)
m[i] = new int [z];
int **s = new int *[z];
for(int j = 1; j < z; j ++)
s[j] = new int [z];
for(int i=1;i<z;i++)
for(int j=1;j<z;j++)
m[i][j]=r[i][j]; //初始化m数组,m[i][j]的初始值为租金r[i][j]
for (int i = 1; i <z; i++)
for(int j=1;j<z;j++)
{
s[i][j] = j; //初始化s数组,初始值表示在j换船
}
MatrixChain( z-1, m, s); //求最优值
cout<<"最优值矩阵m:"<<endl;
Print(m,z-1,z-1); //显示二维数组m
cout<<"最优解矩阵s:"<<endl;
Print(s,z-1,z-1); //显示二维数组s
cout<<"最优值:m[1]["<<z-1<<"]="<<m[1][z-1]<<endl<<endl;
cout<<"最优换船位置:";
Traceback(1,z-1,s); //求最优解
cout<<endl;
return 0;
}
改写的二分搜索 :
#include <iostream>
using namespace std;
template<class Type>
int BinarySearch(Type a[ ],const Type& x,Type left,Type right,Type &i,Type &j )
{
while (left<=right){
Type mid = (left+right)/2;
if (x == a[mid]) {i=j=mid; return 1;}
if (x < a[mid]) right = mid-1;
else left = mid+1;
}
i=right; j=left;
return 0;
}
int main()
{ int a[5]={0,1,2,3,5};
int x=3;
int i,j,k;
k=BinarySearch(a,x,0,4,i,j);
if (k==1)
cout<<"found x"<<endl;
else
cout<<"not found x"<<endl;
cout<<"i="<<i<<endl;
cout<<"j="<<j<<endl;
return 0;
}