100道动态规划——14 UVA 1412 Fund Management 从刘汝佳dalao的代码里学到了很多。。。。
2016-11-26 21:35
357 查看
好吧。之所以有一段时间没有发100道动态规划系列了,一是最近有点事情,而是为了这道题刷了刷前面的数据结构那一章的题目。
我感觉这个代码里面学到了很多东西,因此就不说自己的感想了,全写在代码注释里面了,学习了。。
我感觉这个代码里面学到了很多东西,因此就不说自己的感想了,全写在代码注释里面了,学习了。。
// UVa1412 Fund Management // Rujia Liu #include<cstdio> #include<cstring> #include<vector> #include<map> using std::map; using std::vector; const double INF = 1e30; const int maxn = 8; const int maxm = 100 + 5; const int maxstate = 15000; int m, n, s[maxn], k[maxn], kk; double c, price[maxn][maxm]; char name[maxn][10]; double d[maxm][maxstate]; int opt[maxm][maxstate], prev[maxm][maxstate]; //prev在最优解的上一个状态的s,实际上opt是可以省略掉的,只通过s判断就可以得出答案,此处是为了在打印解的时候更加方便。 //buy_next表示当前状态是s,买了第i只股票后的状态的ID int buy_next[maxstate][maxn], sell_next[maxstate][maxn];//之所以有这两个数组的原因,利用空间换取在ID上O(lgn)的查询时间,这时只需要查表就可以知道下一个状态的ID,不过需要注意下一个状态不存在的情况 vector<vector<int> > states;//构建从ID到state的O(1)映射 map<vector<int>, int> ID;//构建从state到ID的O(lgn)映射 //lots是当前的状态,totlot是当前的总量,stock代表当前处理到了第stock只股票 void dfs(int stock, vector<int>& lots, int 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; 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; //i表示第i只股票 for(int i = 0; i < n; i++) totlot += states[s][i]; for(int i = 0; i < n; i++) { //-1表示无效的状态 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) { vector<int> newstate = states[s]; newstate[i]--; sell_next[s][i] = ID[newstate]; } } } } //刷表法 v是之后的价值,s2之操作之后的状态,s是当前的状态,o储存了两个信息,一个是通过正负或者0来表示相应的操作,同时记录了是哪一只股票的操作。 //因为我们的股票是从0开始,编号的,因此在处理的时候需要+1或者-1来和0进行区分 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; prev[day+1][s2] = s; } } double dp() { for(int day = 0; day <= m; day++) for(int s = 0; s < states.size(); s++) d[day][s] = -INF; 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 < -1) continue; update(day, s, s, v, 0); // HOLD //i表示第i只股票 for(int i = 0; i < n; i++) { if(buy_next[s][i] >= 0 && v >= price[i][day] - 1e-3) update(day, s, buy_next[s][i], v - price[i][day], i+1); // BUY if(sell_next[s][i] >= 0) update(day, s, sell_next[s][i], v + price[i][day], -i-1); // SELL } } return d[m][0]; } //递归输出解,prev表示当前是day天,状态是s的时候,前一天的操作。 void print_ans(int day, int s) { if(day == 0) return; print_ans(day-1, prev[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) == 4) { 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; }
相关文章推荐
- 100道动态规划——2 UVA 1625 Color Length DP 转移的代价稍微难写一点 顺便贴了刘汝佳的代码
- 【暑假】[深入动态规划]UVa 1412 Fund Management
- 【暑假】[深入动态规划]UVa 1412 Fund Management
- 100道动态规划——1 UVA 1347 Tour 算法导论书后习题 双调巡游
- 100道动态规划——6 UVA 1629 Cake slicing 记忆化搜索
- 100道动态规划——29 UVALive 5766 GRE Words AC自动机上的动态规划
- 100道动态规划——36 UVA 1220 Party at Hali-Bula 树形DP 最大独立集 思考欠妥
- 100道动态规划——18 UVA 1336 Fixing the Great Wall 指标函数的分解,刷表法
- 100道动态规划——30 UVAlive 3907 Puzzle AC自动机上的动态规划,记忆化搜索
- 100道动态规划——24 UVA 1633 Dyslexic Gollum 状态压缩DP 挺好的题 因为窝没想到嘛
- 100道动态规划——4 UVA 1331 Maximum Triangulation DP 计算几何
- 100道动态规划——16 UVA 1627 Team them up! 二分图,背包,不过关键还是学会转化
- 100道动态规划——8 UVA 1631 Locker 递推,状态的定义以及状态转移方程
- 100道动态规划——32 UVA 12170 Easy Climb 通过分析减少状态数 单调队列
- 100道动态规划——5 UVA 10118 Free Candies 记忆化搜索 以及 证明状态
- 100道动态规划——13 UVA 10163 Storage Keepers 有约束条件下的DP,递推,不能使用结构体作为基本单位
- 100道动态规划——15 UVA 10618 Tango Tango Insurrection 复杂的转移方程。。
- 100道动态规划——37 UVA 1218 Perfect Service 树形DP 分析问题
- 100道动态规划——34 UVA 10559 Blocks 状态的定义 状态转移方程
- 100道动态规划——26 UVA 12099 The Bookcase 状态的定义,递推,背包