Fund Management UVA - 1412

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

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const double INF = 1e30;
double c;
int m, n, k;
map indToName;
vector> state;
map, 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]<& 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 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 temp = state[i];
					temp[j]++;
					buy_next[i][j] = ID[temp];
				}
				if (state[i][j] > 0){//卖股票
					vector temp = state[i];
					temp[j]--;
					sell_next[i][j] = ID[temp];
 				}
			}
		}
		cout <

你可能感兴趣的:(Uva,oj)