uva1412 基金管理
来源:互联网 发布:装饰质量员 知乎 编辑:程序博客网 时间:2024/04/27 20:14
- 复杂状态做映射。
- 分阶段对每种情况的每种决策做遍历。
- 刷表要好的初始化。
- double数组不能用memset。
- 递归输出可以利用保存的之前下标并从前到后。
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=36228
/*题解思路:*对于复杂状态,初始化映射表,变成整数下标。*构建状态转换表,将复杂状态转换到整数下标。*对于每天,每种情况,每只股票做决策,留,买,卖,对符合条件的进行刷表,刷表的前提是初始化到位*分阶段思想从头刷到尾,利用数组保存解的前一个值,方便遍历。*递归输出,可以利用保存的解并从前到后输出。*/#include<cstdio>#include<cstring>#include<vector>#include<map>using namespace std;const double INF = 1e10;const int maxn = 8;const int maxm = 100 + 5;const int maxstate = 15000;//>2^7*100int m, n, s[maxn], k[maxn], kk;double c, price[maxn][maxm];char name[maxn][10];double d[maxm][maxstate];int opt[maxm][maxstate], pre[maxm][maxstate];int buy_next[maxstate][maxn], sell_next[maxstate][maxn];vector<vector<int> > states;map<vector<int>, int> ID;void dfs(int stock, vector<int>& lots, int totlot) {//totlot表示目前所有股票手数 if(stock == n) { ID[lots] = states.size(); states.push_back(lots); } else for(int i = 0; i <= k[stock] && totlot + i <= kk; i++) { lots[stock] = i;//第stock个股票买了i个,可以买0个。 dfs(stock+1, lots, totlot + i); }}void init() { vector<int> lots(n);//保存每个股票买了几种 states.clear(); ID.clear(); dfs(0, lots, 0);//初始化映射表,每一种购股数情况映射到整数下标 for(int s = 0; s < states.size(); s++) {//遍历所有可能的购股情况 int totlot = 0; for(int i = 0; i < n; i++) totlot += states[s][i];//第一种情况的所有股票数 for(int i = 0; i < n; i++) { buy_next[s][i] = sell_next[s][i] = -1;//标记没有空的情况 if(states[s][i] < k[i] && totlot < kk) {//小于说明还能买一支 vector<int> newstate = states[s]; newstate[i]++; buy_next[s][i] = ID[newstate]; } if(states[s][i] > 0) {//大于0说明还有,还能卖 vector<int> newstate = states[s]; newstate[i]--; sell_next[s][i] = ID[newstate];//标明转换到的状态 } } }}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 dp() { for(int day = 0; day <= m; day++) for(int s = 0; s < states.size(); s++) d[day][s] = -1.0;//浮点数需要逐个赋值,不能用memset d[0][0] = c;//全不买,还剩下原来的现金 for(int day = 0; day < m; day++) for(int s = 0; s < states.size(); s++) { double v = d[day][s]; if(v < 0) continue;//说明还没有处理且不是第一个值 update(day, s, s, v, 0); // HOLD for(int i = 0; i < n; i++) { if(buy_next[s][i] >= 0 && v >= price[i][day] - 1e-3)//下一个状态存在且现金充足,1e-3不写也可以,为了保证精度,写了是一个良好的习惯 update(day, s, buy_next[s][i], v - price[i][day], i+1); // BUY,+1是为了和0区分开 if(sell_next[s][i] >= 0)//如果下一个状态存在 update(day, s, sell_next[s][i], v + price[i][day], -i-1); // SELL } } return d[m][0];//最后一天全卖后}void print_ans(int day, int s) { if(day == 0) return; print_ans(day-1, pre[day][s]); if(opt[day][s] == 0) printf("HOLD\n"); else if(opt[day][s] > 0) printf("BUY %s\n", name[opt[day][s]-1]); else printf("SELL %s\n", name[-opt[day][s]-1]);}int main() { int kase = 0; while(~scanf("%lf%d%d%d", &c, &m, &n, &kk)) { if(kase++ > 0) printf("\n"); for(int i = 0; i < n; i++) { scanf("%s%d%d", name[i], &s[i], &k[i]); for(int j = 0; j < m; j++) { scanf("%lf", &price[i][j]); price[i][j] *= s[i]; }//保存每只股票每天每手的价格 } init(); double ans = dp(); printf("%.2lf\n", ans); print_ans(m, 0); } return 0;}
0 0
- uva1412 基金管理
- UVa1412
- 基金
- 基金
- 基金
- 基金
- 基金
- 《商业银行设立基金管理公司试点管理办法》
- 教你如何选择基金管理公司
- 动态规划(基金管理,uva 1412)
- FOF管理系列之七:基金选择
- 什么是基金的管理费率和托管费率
- 融通基金管理公司郝继伦:做理性的长期投资者
- ECC6.0 IDES基金管理(FM)无法激活解决方法
- 河南农业开发产业投资基金管理有限责任公司
- 担保公司转让ZO投资基金管理公司注册转让
- 资格考试_第一章_金融资产管理与投资基金
- 基金、什么是基金
- SQL统计相同重复的数据
- python datetime
- 【华为 OJ 】字符串分割
- Cpp环境【Vijos1060】斯特林数:盒子与球
- 关于iOS多线程,你看我就够了
- uva1412 基金管理
- 一、iOS初学笔记之swift的基础语法
- 设计模式——策略模式
- zookeeper 入门讲解实例
- 和其他一些面向对象的编程语言一样,不是所有的变量(方法)都要通过创建对象来调用,还可以通过给变量(方法)加上static关键字来直接调用。
- 和其他一些面向对象的编程语言一样,不是所有的变量(方法)都要通过创建对象来调用,还可以通过给变量(方法)加上static关键字来直接调用。
- 和其他一些面向对象的编程语言一样,不是所有的变量(方法)都要通过创建对象来调用,还可以通过给变量(方法)加上static关键字来直接调用。
- 和其他一些面向对象的编程语言一样,不是所有的变量(方法)都要通过创建对象来调用,还可以通过给变量(方法)加上static关键字来直接调用。
- 和其他一些面向对象的编程语言一样,不是所有的变量(方法)都要通过创建对象来调用,还可以通过给变量(方法)加上static关键字来直接调用。