算法导论 第15章 动态规划 习题C++实现

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);

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值