算法导论之动态规划 签约棒球自由球员
Posted 童话的守望者
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法导论之动态规划 签约棒球自由球员相关的知识,希望对你有一定的参考价值。
假设你是一支棒球大联盟球队的总经理。在赛季休季期间,你需要签入一些自由球员。球队老板给你的预算为X美元,你可以使用少于X美元来签入球员,但如果超支,球队老板就会解雇你。
你正在考虑在N个不同位置签入球员,在每个位置上,有P个该位置的自由球员供你选择。由于你不希望任何位置过于臃肿,因此每个位置最多签入一名球员(如果在某个特定位置上你没有签入任何球员,则意味着计划继续使用现有球员)。
为了确定一名球员的价值,你决定使用一种称为“VORP”,或“球员替换价值”的统计评价指标。球员的VORP值越高,其价值越高。但VORP值高的球员签约费用并不一定比VORP值低的球员高,因为还有球员价值之外的因素影响签约费用。
对于每个可选择的自由球员,你知道他的三方面信息:
1.他打哪个位置。2.他的签约费用。3.他的VORP。
设计一个球员选择算法,是的总签约费用不超过X美元,而球员的总VORP最大。你可以假定每位球员的签约费用是10万美元的整数倍。算法应输出签约球员的总VORP值,总签约费用,以及球员名单。分析算法的时间和空间复杂度。
问题分析:此题是一规划问题,类似与背包问题,想深入理解这一系列问题的人可以去看看大神讲的背包九讲。
在解决问题的方法论上,总结寻找规律,是最好的一种方法了。如下表:
费用 位置 | 10 | 20 | 30 | 40 | 50 | 60 | 70 | 80 | 90 | 100 | 110 |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
2 | 2 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 |
3 | 0 | 4 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 |
4 | 3 | 4 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 |
5 | 5 |
|
|
|
|
|
|
|
|
|
|
6 | 3 |
|
|
|
|
|
|
|
|
|
|
7 | 3 |
|
|
|
|
|
|
|
|
|
|
8 | 0 |
|
|
|
|
|
|
|
|
|
|
9 | 0 |
|
|
|
|
|
|
|
|
|
|
10 | 0 |
|
|
|
|
|
|
|
|
|
|
11 | 1 |
|
|
|
|
|
|
|
|
|
|
如果尝试去填写这一张表,大家就会发现其中的规律,也会明白为什么这个题可以用动态规划算法去求解。上表的规律可以总结如下几点:
1.从上到下,从左至右求解
2.求解中有许多重叠的子问题,如单元格(4,30)的求解等于(4,20)与(3,20)与(4,10)的求解。
我们可以从中发现动态规划问题的两大特点:最优子结构与重叠子问题,都是满足的。
#include <iostream>
#define total_pos 10
#define max_money 200
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
typedef struct
int cost;
int vorp;
player;
int main()
//输入部分
int vorp[11][max_money+1]=-1;// 浪费空间,网友可以好好修改下,vorp[i][j]表示前i个位置在j美元限制下最大的vorp;
player baseball[11][7]; // baseball[i][j]表示第i个位置第j个候选人;
cout<<"****** cos*******vorp"<<endl;
for(int i=1;i<=10;i++)
for(int j=1;j<=6;j++)
cin>>baseball[i][j].cost>>baseball[i][j].vorp;
//输入部分结束
//算法初始化部分
for(int j=10;j<=max_money;j=j+10)
baseball[1][0].vorp=-1;
for(int k=1;k<=7;k++)
if(baseball[1][k].cost<=max_money&&baseball[1][k].vorp>=baseball[1][k-1].vorp)
vorp[1][j]=baseball[1][k].vorp;
//算法初始化部分结束
//递归实现部分
for(int i=2;i<=10;i++)
for(int j=10;j<=max_money;j+=10)
baseball[i][0].vorp=-1;
for(int k=1;k<=6;k++)
if(j-baseball[i][k].cost>0&&baseball[i][k].vorp>=baseball[i][k-1].vorp)
vorp[i][j]=max(vorp[i][j-10],vorp[i-1][j-baseball[i][k].cost]+baseball[i][k].vorp);
//递归实现结束
cout<<"the result is "<<vorp[10][max_money];
return 0;
以上是关于算法导论之动态规划 签约棒球自由球员的主要内容,如果未能解决你的问题,请参考以下文章