题目:
15.3-6假定你希望兑换外汇,你意识到与其直接兑换,不如进行多种外币的一系列兑换,最后兑换到你想要的那种外币,可能会获得更大收益。假定你可以交易n种不同的货币,编号为1,2.....n,兑换从1号货币开始,最终兑换为n号货币。对每两种货币i和j给定汇率rij,意味着你如果有d个单位的货币i,可以兑换dr0个单位的货币j.进行一系列的交易需要支付一定的佣金,金额取决于交易次数。令ck表示k次交易需要支付的佣金。证明:如果对所有k=1,2...n,ck=0,那么寻找最优兑换序列的问题具有最优子结构性质。然后请证明:如果佣金ck为任意值,那么问题不一定具有最优子结构性质。
题目虽然没有要求写出算法,但我也给出算法。
//15.3-6多次兑换货币换取最大收益 #include <iostream> using namespace std; #define n 4 struct Currency_Exchange { double **r;//储存汇率 int *s;//储存外汇最佳方式的变量 Currency_Exchange() { r=new double *[n]; for (int i=0;i<n;i++) { r[i]=new double[n]; } s=new int [n]; } }; struct Best_Currency_Exchange { static double Max;//最大收益 static double Min;//最小收益 int *t; static int end; Best_Currency_Exchange() { t=new int[n]; } }; double Best_Currency_Exchange::Max=-0x7fffffff; double Best_Currency_Exchange::Min=0x7fffffff; int Best_Currency_Exchange::end=0x7fffffff; void init(Currency_Exchange T,Best_Currency_Exchange Result)//结构体的初始化 { for (int i=0;i<n;i++) { for (int j=0;j<n;j++) { T.r[i][j]=-0x7fffffff; } T.s[i]=-0x7fffffff; Result.t[i]=-0x7fffffff; } Result.end=-1; } inline void swap(int* array, unsigned int i, unsigned int j) { int t = array[i]; array[i] = array[j]; array[j] = t; } void Print(int i) { switch (i) { case 0:cout<<"欧元(EUR-1)-->"; break; case 1:cout<<"坡元(SGD-2)-->"; break; case 2:cout<<"加元(CAD-4)-->"; break; case 3:cout<<"澳元(AUD-3)-->"; break; case 4:cout<<"日元(JPY)-->"; break; case 5:cout<<"台币(CHF)-->"; break; case 6:cout<<"英镑(GBP)-->"; break; default: cout<<"超出范围,输入错误!"<<endl; break; } } Best_Currency_Exchange FullArray(int* array, size_t array_size, unsigned int index,Currency_Exchange T,Best_Currency_Exchange Result) { static int k=0; if(index>=0) { k++; int j=0; cout<<"k="<<k<<":"; double m=1.0; if (index>=1) { m*=T.r[0][array[0]]; T.s[0]=0; for(unsigned int i = 0; i < index; ++i) { // cout <<array[i] << ' '; Print(array[i]);cout<<' '; T.s[i+1]=array[i]; if (i==index-1) { m*=T.r[array[i]][n-1]; } else m*=T.r[array[i]][array[i+1]]; } if(i<n-1) { T.s[i+1]=n-1; } i++; j=i; } else if(index==0) { m=T.r[0][n-1]; T.s[j++]=0; T.s[j++]=n-1; } cout<<"m="<<m; if (Result.Max<m) { Result.Max=m; Result.end=j; for (int q=0;q<=Result.end;q++) { Result.t[q]=T.s[q]; } } if (Result.Min>m) { Result.Min=m; } cout << '\n'; } if (index==array_size) { return Result; } for(unsigned int i = index; i < array_size; ++i) { swap(array, i, index); FullArray(array, array_size, index + 1,T,Result); swap(array, i, index); } return Result; } void main() { Currency_Exchange T; Best_Currency_Exchange Result; init(T,Result);//结构体的初始化 for (int i=0;i<n;i++) { for (int j=0;j<n;j++) { cout<<"请输入"; Print(i); cout<<"-->"; Print(j); cin>>T.r[i][j]; cout<<endl; } } int array[n-2]={1,2}; Best_Currency_Exchange Result1=FullArray(array, n-2,0, T,Result); cout<<"最佳兑换方式:"; for (int k=0;k<=Result1.end;k++) { if (Result1.t[k]>-0x7fffffff) { Print(Result1.t[k]); } } cout<<endl; cout<<"最大收益为:"; cout<<Result1.Max<<endl; cout<<"最小收益为:"; cout<<Result1.Min<<endl; cout<<"两者差值为:"<<endl; cout<<Result1.Max-Result1.Min<<endl; }
数据实例图:
不加额外手续费的结果图:
如果算上额外任意手续费就会如下图:
总结:
故手续费为0时,可以用最优子结构,手续费任意时就不能用了。
第三版《算法导论》中的15.3-6关于动态规划新增题解
时间: 2024-11-05 04:51:34