BZOJ1578 USACO 2009 Feb Gold 2.Stock Market

题意:有S种股票,我们已经知道每一天每一种股票的价格。一共有d天,一开始拥有的钱为m,求最后总共能够拥有多少钱。


Sol:

一开始我十分沙茶。。

我们设dp[i]表示第i天能够拥有的最大价值。于是我们枚举上一次买股票时间j,然后以dp[j]为容量做完全背包。这样的总时间复杂度为O(msd^2).显然是超时的。


事实上,我们只需从第i-1天进行转移即可。因为若有若干天没有买股票,也同样可以通过完全背包转移,进行考虑后是很显然的。

于是总的时间复杂度变为O(msd),要求常数优化到位。


Code:

#include <cstdio>
#include <cstring>
#include <cctype>
#include <iostream>
#include <algorithm>
using namespace std;

#define S 51
#define D 11
#define M 500010
int p[D][S], best[D], dp[M];

int tmp[S], top;

#define _max(a, b) ((a)>(b)?(a):(b))

int main() {
	int s, d, m;
	scanf("%d%d%d", &s, &d, &m);
	
	int i, j, k;
	for(i = 1; i <= s; ++i)
		for(j = 1; j <= d; ++j)
			scanf("%d", &p[j][i]);
	
	best[1] = m;
	for(i = 2; i <= d; ++i) {
		top = 0;
		for(j = 1; j <= s; ++j)
			if (p[i][j] > p[i - 1][j])
				tmp[++top] = j;
		for(k = 1; k <= best[i - 1]; ++k)
			dp[k] = k;
		for(j = 1; j <= top; ++j)
			for(k = p[i - 1][tmp[j]]; k <= best[i - 1]; ++k)
				dp[k] = _max(dp[k], dp[k - p[i - 1][tmp[j]]] + p[i][tmp[j]]);
		best[i] = _max(best[i], dp[best[i - 1]]);
	}
	
	printf("%d", best[d]);
	
	return 0;
}


你可能感兴趣的:(BZOJ1578 USACO 2009 Feb Gold 2.Stock Market)