标签:
戳这里:3401
题意:给出第 i 天的股票买卖价格(APi,BPi),以及每天股票买卖的数量上限(ASi,BSi),要求任两次交易需要间隔 W 天以上,即第 i 天交易,第 i + W + 1 天才能再交易,求最多能赚多少钱
思路:dp[i][j] = max(dp[i - 1][j], max(dp[f][k] - (j - k) * APi[i]), max(dp[f][k] + (k - j) * BPi[i])); 从式子中观察出,若两天都持有股票数 j 时,之后的那一天所赚的钱不小于之前的那一天,所以可以省去对 f 的枚举,即:
dp[i][j] = max(dp[i - 1][j], max(dp[i - 1 - w][k] - (j - k) * APi[i]), max(dp[i - 1 - w][k] + (k - j) * BPi[i]));
观察到,决策2 j > k,决策3 k > j,且两天所持股票数相近的话,发生状态转移的可能性越大,故可以对 k 进行单调队列优化,
决策2 化为 max(dp[i - 1 - w][k] + k * APi[i]) - j * APi[i]; (j >= k)
决策3 化为 max(dp[i - 1 - w][k] + k * BPi[i]) - j * BPi[i]; (j <= k)
1 #include "bits/stdc++.h" 2 using namespace std; 3 int t; 4 int T, MaxP, W; 5 int APi[2010], BPi[2010], ASi[2010], BSi[2010]; 6 7 int dp[2010][2010]; 8 struct Queue 9 { 10 int value, index; 11 }q[2010], tmp; 12 int front, rear; 13 14 //dp[i][j] = max(dp[i - 1][j], max(dp[i - 1 - w][k] - (j - k) * APi[i]), max(dp[i - 1 - w][k] + (k - j) * BPi[i])); 15 //决策2 化为 max(dp[i - 1 - w][k] + k * APi[i]) - j * APi[i]; (j >= k) 16 //决策3 化为 max(dp[i - 1 - w][k] + k * BPi[i]) - j * BPi[i]; (j <= k) 17 18 int main() 19 { 20 scanf("%d", &t); 21 while(t--) { 22 //初始化 23 memset(dp, 0xf3, sizeof(dp)); 24 //输入 25 int i, j, k; 26 scanf("%d%d%d", &T, &MaxP, &W); 27 for(i = 1; i <= T; ++i) { 28 scanf("%d%d%d%d", &APi[i], &BPi[i], &ASi[i], &BSi[i]); 29 } 30 //处理前驱不完全的状态 31 for(i = 1; i <= W + 1; ++i) { 32 for(j = 0; j <= ASi[i]; ++j) { //之前这里写成 j <= MaxP WA了一次 33 dp[i][j] = -j * APi[i]; 34 } 35 } 36 //从首个后继状态开始 dp 37 for(i = 2; i <= T; ++i) { 38 //决策1 39 for(j = 0; j <= MaxP; ++j) { 40 dp[i][j] = max(dp[i][j], dp[i - 1][j]); 41 } 42 if(i <= W + 1) { 43 continue; 44 } 45 //决策2 46 front = rear = 1; 47 for(j = 0; j <= MaxP; ++j) { 48 tmp.index = j; 49 tmp.value = dp[i - 1 - W][j] + j * APi[i]; 50 for( ; front < rear && tmp.value > q[rear - 1].value; --rear); 51 q[rear++] = tmp; 52 for( ; front < rear && q[front].index + ASi[i] < j; ++front); 53 dp[i][j] = max(dp[i][j], q[front].value - j * APi[i]); 54 } 55 //决策3 56 front = rear = 1; 57 for(j = MaxP; j >= 0; j--) { 58 tmp.index = j; 59 tmp.value = dp[i - 1 - W][j] + j * BPi[i]; 60 for( ; front < rear && tmp.value > q[rear - 1].value; --rear); 61 q[rear++] = tmp; 62 for( ; front < rear && q[front].index - BSi[i] > j; ++front); 63 dp[i][j] = max(dp[i][j], q[front].value - j * BPi[i]); 64 } 65 } 66 int res = 0; 67 for(j = 0; j <= MaxP; ++j) { 68 res = max(res, dp[T][j]); 69 } 70 printf("%d\n", res); 71 } 72 }
标签:
原文地址:http://www.cnblogs.com/AC-Phoenix/p/4487188.html