您的位置:首页 > 其它

Fund Management UVA - 1412

2017-09-19 15:29 441 查看
一道动态规划的题目,有点难......首先是找到所有股票的合法的组合状态,合法也就是单个股票的持有股数不超过上限,所有股票的持有股数和不超过上限,并且对于每一种组合的方式都设置一个整数来代表其ID号,后续处理当中一个整数也就代表着一种股票的组合方式。然后就是在不考虑金钱的情况下,计算出每种组合方式的每个股票是否能够进行相应的买和卖,如果可以的话,就计算出买或者卖之后的股票组合的状态的ID号,并且记录。最后来考虑金钱,对于从最开始的持有C美元,然后判断每天中每种状态下的每只股票是否能买以及能卖,如果可以买也可以卖,那么就对状态进行相应的更新和记录,最后逆向查找,顺序打印最终结果即可,具体实现见如下代码:

#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<deque>
using namespace std;
const double INF = 1e30;
double c;
int m, n, k;
map<int, string> indToName;
vector<vector<int>> state;
map<vector<int>, int> ID;
double d[110][13000];
int pre[110][13000], opt[110][13000];
int upper[8];
int buy_next[13000][8], sell_next[13000][8];
double price[8][110];

void update(int day,int s,int s2,double v,int o){
if (v > d[day + 1][s2]){
d[day + 1][s2] = v;
opt[day + 1][s2] = o;//最优
pre[day + 1][s2] = s;
}
}

double getResult(){//股票数是n,天数是m

for (int i = 0; i <= m; i++){
for (int j = 0; j < state.size(); j++){
d[i][j] = -INF;//d代表的是余额
}
}
d[0][0] = c;
for (int i = 0; i < m; i++){
for (int j = 0; j < state.size(); j++){
double value = d[i][j];
if (value < 0) continue;
update(i, j, j, value, 0);
for (int k = 0; k < n; k++){
if (buy_next[j][k] >= 0 && value >= price[k][i]-1e-3){
update(i, j, buy_next[j][k], value - price[k][i], k + 1);
}
if (sell_next[j][k] >= 0){
update(i, j, sell_next[j][k], value + price[k][i], -k - 1);
}
}
}
}
return d[m][0];
}

void Print(int day,int s){
if (day == 0) return;
Print(day - 1, pre[day][s]);
if (opt[day][s] == 0) cout << "HOLD\n";
else if (opt[day][s]>0) cout << "BUY " << indToName[opt[day][s]-1]<<endl;
else cout << "SELL " << indToName[-opt[day][s]-1] << endl;
}

void dfs(int ind,vector<int>& state1,int cur_total){
if (ind == n){
ID[state1] = state.size();
state.push_back(state1);
return;
}
for (int i = 0; i <= upper[ind] && cur_total+i <= k;i++){
state1[ind] = i;
dfs(ind + 1, state1, cur_total + i);
}
}

int main(){
int flag = 0;
while (cin >> c >> m >> n >> k){//c 美元 m天 n股
if (flag++>0) cout << endl;
indToName.clear(); state.clear(); ID.clear();
for (int i = 0; i < n; i++){
string name;
cin >> name;
indToName[i] = name;
double amount;
cin >> amount >> upper[i];
for (int j = 0; j < m; j++){
double p;
cin >> p;
price[i][j]=p*amount;
}
}
vector<int> state0(n);
dfs(0, state0, 0);
for (int i = 0; i < state.size(); i++){
int cur_total = 0;
for (int j = 0; j < n; j++) cur_total += state[i][j];
for (int j = 0; j < n; j++){
buy_next[i][j] = sell_next[i][j] = -1;
if (state[i][j] < upper[j] && cur_total < k){//买股票
vector<int> temp = state[i];
temp[j]++;
buy_next[i][j] = ID[temp];
}
if (state[i][j] > 0){//卖股票
vector<int> temp = state[i];
temp[j]--;
sell_next[i][j] = ID[temp];
}
}
}
cout <<fixed<<setprecision(2)<< getResult() << endl;
Print(m, 0);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: