chapter15_exercise.h
#ifndef CHAPTER15_EXERCISE_H
#define CHAPTER15_EXERCISE_H
//the excercise of chapter 15
#include<vector>
#include<iostream>
#include<algorithm>
#include<math.h>
const int POS_INFI=1000;
const int NEG_INFI=-1000;
/*class matrix<type>*/
//自定义的matrix模板类
//使用std::vector<type>做容器
template<class type>
class matrix{
public:
matrix();
matrix(int i, int j);
matrix(const matrix& rhs);
//matrix& operator=(const matrix& rhs);
//friend matrix<type>& operator+(const matrix<type>& lhs, const matrix<type>& rhs);
//friend Matirx<type>& operator-(const matrix<type>& lhs, const Matirx<type>& rhs);
const type& operator()(const int i, const int j) const;
type& operator()(const int i, const int j);
const int row()const{ return size1; }
const int col()const{ return size2; }
private:
std::vector<type> mx;
int size1;
int size2;
};
template<class type>
matrix<type>::matrix(int size1_rhs, int size2_rhs) :
size1(size1_rhs),
size2(size2_rhs)
{
mx.resize(size1_rhs*size2_rhs);
}
template<class type>
const type& matrix<type>::operator()(int i, int j) const
{
return mx[i*size2 + j];
}
template<class type>
type& matrix<type>::operator()(int i, int j)
{
return mx[i*size2 + j];
}
//no member funtion
template<class type>
std::ostream& operator<<(std::ostream& os, const matrix<type>& m)
{
for (int i = 0; i < m.row(); i++)
{
for (int j = 0; j < m.col(); j++)
os << m(i, j) << "\t";
os << std::endl;
}
return os;
}
template<class type>
matrix<type>& operator+(const matrix<type>& lhs, const matrix<type>& rhs)
{
matrix<type> mx_rtn(lhs);
for (int i = 0; i < lhs.size1(); i++)
for (int j = 0; j < lhs.size2(); j++)
mx_rtn(i, j) = lhs(i, j) + rhs(i, j);
return mx_rtn;
}
template<class type>
matrix<type>& operator-(const matrix<type>& lhs, const matrix<type>& rhs)
{
matrix<type> mx_rtn(lhs);
for (int i = 0; i < lhs.size1(); i++)
for (int j = 0; j < lhs.size2(); j++)
mx_rtn(i, j) = lhs(i, j) - rhs(i, j);
return mx_rtn;
}
/*class matrix<type>*/
//15-2
void palindrome(const std::vector<char>& x, matrix<int>& c,
matrix<int>& b)
{
int n = x.size() - 1;
for (int i = 1; i <= n; i++)
c(i, i) = 1;
for (int l = 2; l <=n;l++)
for (int i = 1; i <= n - l + 1; i++)
{
int j = i + l - 1;
if (x[i] == x[j])
{
c(i, j) = c(i + 1, j - 1) + 2;
b(i, j) = 1;
}
else if (c(i + 1, j) < c(i, j - 1))
{
c(i, j) = c(i, j - 1);
b(i, j) = 2;
}
else
{
c(i, j) = c(i + 1, j);
b(i, j) = 3;
}
}
}
void print_palindrome(const matrix<int>& b,
const std::vector<char>& x, int i, int j)
{
if (i == j)
{
std::cout << x[i];
return;
}
if (b(i, j) == 1)
{
std::cout << x[i];
print_palindrome(b, x, i + 1, j - 1);
std::cout << x[i];
}
else if (b(i, j) == 2)
print_palindrome(b, x, i, j - 1);
else if (b(i, j) == 3)
print_palindrome(b, x, i + 1, j);
else
std::cerr << "printing error" << std::endl;
}
//15-3
double euc_dis(const std::vector<double>& px,
const std::vector<double>& py,
int m,int n)
{
return sqrt((px[m]-px[n])*(px[m]-px[n])+(py[m]-py[n])*(py[m]-py[n]));
}
void euclidean_tsp(const std::vector<double>& px,
const std::vector<double>& py,
matrix<double>& b,matrix<int>& r)
{
int n=px.size()-1;
b(1,2)=euc_dis(px,py,1,2);
for(int j=3;j<=n;j++)
{
for(int i=1;i<=j-2;i++)
{
b(i,j)=b(i,j-1)+euc_dis(px,py,j-1,j);
r(i,j)=j-1;
}
b(j-1,j)=POS_INFI;
for(int k=1;k<=j-2;k++)
{
double q=b(k,j-1)+euc_dis(px,py,k,j);
if(q<b(j-1,j))
{
b(j-1,j)=q;
r(j-1,j)=k;
}
}
}
b(n,n)=b(n-1,n)+euc_dis(px,py,n-1,n);
}
void print_path(const matrix<int>&r,int i,int j)
{
if(i<j)
{
int k=r(i,j);
if(k!=i)
std::cout<<k<<std::endl;
if(k>1)
print_path(r,i,k);
}
else
{
int k=r(j,i);
if(k>1)
{
print_path(r,k,j);
std::cout<<k<<std::endl;
}
}
}
void print_tour(const matrix<int>& r,int n)
{
std::cout<<n<<std::endl;
std::cout<<n-1<<std::endl;
int k=r(n-1,n);
print_path(r,k,n-1);
std::cout<<k<<std::endl;
}
//15-4 print neatly
void print_neatly(const std::vector<int>& l,int n,int m,
matrix<int>& extras,matrix<int>& lc,std::vector<int>& c,std::vector<int>& p)
{
for(int i=1;i<=n;i++)
{
extras(i,i)=m-l[i];
for(int j=i+1;j<=n;j++)
extras(i,j)=extras(i,j-1)-l[j]-1;
}
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++)
{
if(extras(i,j)<0)
lc(i,j)=POS_INFI;
else if(j==n&&extras(i,j)>=0)
lc(i,j)=0;
else lc(i,j)=(extras(i,j))^3;
}
c[0]=0;
for(int j=1;j<=n;j++)
{
c[j]=POS_INFI;
for(int i=1;i<=j;i++)
if(c[i-1]+lc(i,j)<c[j])
{
c[j]=c[i-1]+lc(i,j);
p[j]=i;
}
}
}
int give_lines(std::vector<int>& p,int j)
{
int i=p[j];
int k=1;
if(i!=1)
k=give_lines(p,i-1)+1;
std::cout<<"line:"<<k<<"\tcontains\t"<<i<<"\t-->\t"<<j<<std::endl;
return k;
}
//15-5 edit distance
void op_sequence(matrix<int>& op,int kill,int i,int j)
{
int ii,int jj;
if(i==0&&j==0)
return;
if(op(i,j)==0||op(i,j)==1)
{
ii=i-1;
jj=j-1;
}
else if(op(i,j)==4)
{
ii=i-2;
jj=j-2;
}
else if(op(i,j)==2)
{
ii=i-1;
jj=j;
}
else if(op(i,j)==3)
{
ii=i;
jj=j-1;
}
else
{
ii=kill;
jj=j;
}
op_sequence(op,kill,i,j);
std::cout<<op(i,j)<<std::endl;
}
void edit_distance(std::vector<int>& x,std::vector<int>& y,std::vector<int>& cost,
int m,int n,int kill,matrix<int>& c,matrix<int>& op)
{
for(int i=0;i<=m;i++)
{
c(i,0)=i*cost[2];
op(i,0)=2;
}
for(int j=0;j<=n;j++)
{
c(0,j)=j*cost[3];
op(0,j)=3;
}
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
{
c(i,j)=POS_INFI;
if(x[i]==y[j])
{
c(i,j)=c(i-1,j-1)+cost[0];
op(i,j)=0;
}
if(x[i]!=y[j]&&c(i-1,j-1)+cost[1]<c(i,j))
{
c(i,j)=c(i-1,j-1)+cost[1];
op(i,j)=1;
}
if(i>=2&&j>=2&&x[i]==y[j-1]&&x[i-1]==y[j]
&&c(i-1,j-2)+cost[4]<c(i,j))
{
c(i,j)=c(i-2,j-2)+cost[4];
op(i,j)=4;
}
if(c(i-1,j)+cost[2]<c(i,j))
{
c(i,j)=c(i-1,j)+cost[2];
op(i,j)=2;
}
if(c(i,j-1)+cost[3]<c(i,j))
{
c(i,j)=c(i,j-1)+cost[3];
op(i,j)=3;
}
}
for(int i=0;i<=m-1;i++)
if(c(i,n)+cost[5]<c(m,n))
{
c(m,n)=c(i,n)+cost[5];
op(m,n)=5;
kill=i;
}
}
//15-8 break string
void print_break(std::vector<int>& l,matrix<int>& b,int i,int j)
{
if(j-i>=2)
{
int k=b(i,j);
std::cout<<" break at:"<<k;
print_break(l,b,i,k);
print_break(l,b,k,j);
}
}
void break_string(int m,std::vector<int>& l,matrix<int>& c,matrix<int>& b)
{
for(int i=1;i<=m-1;i++)
c(i,i)=c(i,i+1)=0;
c(m,m)=0;
for(int len=3;len<=m;len++)
for(int i=1;i<=m-len+1;i++)
{
int j=i+len-1;
c(i,j)=POS_INFI;
for(int k=i+1;k<j-1;k++)
if(c(i,k)+c(k,j)<c(i,j))
{
c(i,j)=c(i,k)+c(k,j);
b(i,j)=k;
}
c(i,j)+=l[j]-l[i];
}
std::cout<<"the minimum cost is :"<<c(1,m)<<std::endl;
print_break(l,b,1,m);
}
//15-11 inventory planning
void inventory_planning(int n,int m,int c,int D,std::vector<int>& d,
matrix<int>& cost,matrix<int>& make,int h (int))
{
for(int s=0;s<=D;s++)
{
int f=std::max(d[n]-s,0);
cost(n,s)=std::max(f-m,0)+h(s+f-d[n]);
make(n,s)=f;
}
int u=d[n];
for(int k=n-1;k>=1;k--)
{
u+=d[k];
for(int s=0;s<=D;s++)
{
cost(k,s)=POS_INFI;
for(int f=std::max(d[k]-s,0);f<=u-s;f++)
{
int val=cost(k+1,s+f-d[k])+
c*std::max(f-m,0)+h(s+f-d[k]);
if(val<cost(k,s))
{
cost(k,s)=val;
make(k,s)=f;
}
}
}
}
std::cout<<cost(1,0)<<std::endl;
int s=0;
for(int k=1;k<=n;k++)
{
std::cout<<" month "<<k<<" make"<<make(k,s)<<std::endl;
s+=s+make(k,s)-d[k];
}
}
//15-12 base ball players
void free_agent_vorp(const matrix<int>& cost,const matrix<int>& vorp,
int budget,int P,matrix<int>& v,matrix<int>& who)
{
int N=cost.row();
for(int x=0;x<=budget;x++)
{
v(N,x)=NEG_INFI;
who(N,x)=0;
for(int k=1;k<=P;k++)
if(cost(N,k)<=x&&vorp(N,k)>=v(N,x))
{
v(N,x)=vorp(N,k);
who(N,x)=k;
}
}
for(int i=N-1;i>=1;i--)
for(int x=0;x<=budget;x++)
{
v(i,x)=v(i+1,x);
who(i,x)=0;
for(int k=1;k<=P;k++)
if(cost(i,k)<=x&&v(i+1,x-cost(i,k))+vorp(i,k)>v(i,x))
{
v(i,x)=v(i+1,x-cost(i,k))+vorp(i,k);
who(i,x)=k;
}
}
std::cout<<"the maximum vorp is:"<<v(1,budget)<<std::endl;
int amt=budget;
for(int i=1;i<=N;i++)
{
int k=who(i,amt);
if(k!=0)
{
std::cout<<"sign player "<<k<<std::endl;
amt-=cost(i,k);
}
}
std::cout<<"total money spend:"<<budget-amt<<std::endl;
}
#endif
chapter15_exercise_test.cpp
#include"chapter15_exercise.h"
void main()
{
//char carray[] = { 's','c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r' };
//std::vector<char> x(carray, carray + sizeof(carray) / sizeof(char));
//int n = x.size() - 1;
//matrix<int> c(n + 1, n + 1);
//matrix<int> b(n + 1, n + 1);
//palindrome(x, c, b);
//std::cout << c << std::endl;
//std::cout << b << std::endl;
//print_palindrome(b, x, 1, n);
//double pxarray[]={0,1,2,3,4,5,6,7};
//double pyarray[]={0,7,1,4,5,2,6,3};
//std::vector<double> px(pxarray,
// pxarray+sizeof(pxarray)/sizeof(double));
//std::vector<double> py(pyarray,
// pyarray+sizeof(pyarray)/sizeof(double));
//int n=px.size()-1;
//matrix<double> b(n+1,n+1);
//matrix<int> r(n,n+1);
//euclidean_tsp(px,py,b,r);
//std::cout<<r<<std::endl;
//print_tour(r,n);
const int n=100;
const int m=20;
std::vector<int> l(n+1,0);
for(int i=0;i<=n;i++)
l[i]=rand()%3+2;
matrix<int> extras(n+1,n+1);
matrix<int> lc(n+1,n+1);
std::vector<int> c(n+1,0);
std::vector<int> p(n+1,0);
print_neatly(l,n,m,extras,lc,c,p);
give_lines(p,n);
}