动态规划(DP) 之优先队列优化 HDOJ 3401Trade
来源:互联网 发布:win32编程教程 编辑:程序博客网 时间:2024/06/07 12:34
HDOJ 3401题目连接
告诉你 T 天里,物品的买卖价格,和当天最多买卖数量,还有 T 天里最多保存物品数量,每一次买卖间隔时间必须大于 w+1
很容易想到DP【i】【j】表示,第i天结束的时候还保存有j个物品时的最大获利
初始化dp【i】【j】 = dp【i-1】【j】;
那么状态方程dp【i】【j】 = MAX(dp【k】【j】),其中k<= i - w - 1;
且有 dp【i】【j】=MAX(dp【k】【z】 - (j - z) * buyValue【i】),其中,k<=i-w-1,z<j且 z>=j-maxBuy【i】;
还有 dp【i】【j】=MAX(dp【k】【z】 + (z - j) * sellValue【i】),其中,k<=i-w-1,z>j且 z<=j + maxSell【i】;
所以会有i,j,z三层循环,而他们的范围都是2000,所以有2000^3的复杂度,肯定超时
这个时候我们可以用优先队列来优化,使之少一层循环
z<j且 z>=j-maxBuy【i】的时候,dp【i】【j】= dp【k】【z】 - (j - z) * buyValue【i】= dp【k】【z】 + z * buyValue【i】 - j*buyValue【i】
可以发现dp【k】【z】 + z * buyValue【i】部分只与z有关;
- j*buyValue【i】而后面的部分只与j有关,所有z都一样;
所以我们需要的是式子前面这一部分的值越大越好,而z的范围又随着j的变化而变化,刚好是优先队列的使用情况
这个题目有注意的地方
(1)就是k可以定为i-w-1,因为i-w-1之前的所有并没有比i-w-1优,相反i-w-1这一天有可能比前面的优
(2)别忘了i可以从i-1天来
(3)最后的答案其实一定是剩余0个物品的时候
我的代码:
#include<stdio.h>
//#include<string.h>
//#include<algorithm>
#define CANNOT (-0x3fffffff)
#define MAX 2100
int dp[MAX][MAX];
int days[MAX][4];
int que[MAX], tail, front;
int where[MAX];
int t, maxp, w;
int Max(int a, int b)
{
return a > b ? a : b;
}
int main()
{
int i, j;
int cases;
int result;
int xx;
scanf("%d", &cases);
while(cases --)
{
result = 0;
scanf("%d%d%d", &t, &maxp, &w);
for(i = 1; i <= t; i ++)
{
scanf("%d%d%d%d", &days[i][0], &days[i][1], &days[i][2], &days[i][3]);
}
for(i = 1; i <= t; i ++)
{
if(i <= w + 1)
{
for(j = 0; j <= maxp; j ++)
{
if(j <= days[i][2])
{
dp[i][j] = -j * days[i][0];
}
else
{
dp[i][j] = CANNOT;
}
if(i > 1)
dp[i][j] = Max(dp[i][j], dp[i - 1][j]);
}
}
else
{
for(j = 0; j <= maxp; j ++)
{
dp[i][j] = dp[i - w - 1][j];
dp[i][j] = Max(dp[i][j], dp[i - 1][j]);
}
tail = -1;
front = 0;
int temp = 0;
for(j = 0; j <= maxp; j ++)
{
while(temp < j)
{
if(dp[i - w - 1][temp] == CANNOT)
{
temp ++;
continue;
}
xx = dp[i - w - 1][temp] + temp * days[i][0];
while(front <= tail)
{
if(xx >= que[tail])
tail --;
else
break;
}
que[++ tail] = xx;
where[tail] = temp;
temp ++;
}
while(front <= tail && j - where[front] > days[i][2])
{
front ++;
}
if(front <= tail)
dp[i][j] = Max(dp[i][j], que[front] - j * days[i][0]);
}
tail = -1;
front = 0;
temp = 0;
for(j = 0; j <= maxp; j ++)
{
while(temp <= j + days[i][3] && temp <= maxp)
{
if(dp[i - w - 1][temp] == CANNOT || temp <= j)
{
temp ++;
continue;
}
xx = dp[i - w - 1][temp] + temp * days[i][1];
while(front <= tail)
{
if(xx >= que[tail])
tail --;
else
break;
}
que[++ tail] = xx;
where[tail] = temp;
temp ++;
}
while(front <= tail && where[front] <= j)
{
front ++;
}
if(front <= tail)
dp[i][j] = Max(dp[i][j], que[front] - j * days[i][1]);
}
}
}
// result = 0;
// for(i = 0; i <= maxp; i ++)
// result = Max(result, dp[t][i]);
// printf("%d\n", result);
printf("%d\n", dp[t][0]);
}
return 0;
}
- 动态规划(DP) 之优先队列优化 HDOJ 3401Trade
- HDOJ 3401 Trade(单调队列优化DP)
- HDOJ 3401 Trade (单调队列优化)
- HDU 3401 Trade (单调队列优化DP)
- HDU-3401:Trade(dp+单调队列优化)
- HDU 3401 Trade(单调队列优化DP)【模板】
- HDU 3401 Trade(用单调队列优化DP)
- hdu 3401 Trade(DP+单调队列优化)
- hdu 3401 Trade 单调队列优化dp
- hdu 3401 Trade 单调队列优化dp
- hdu 3401 Trade(单调队列优化dp)
- HDU 3401 Trade 单调队列优化DP
- HDU 3401 Trade 【DP+单调队列优化】
- hdu3401 Trade(单调队列优化dp)
- hdu-3401-Trade-单调队列优化的DP
- Hdu3401 Trade(dp 单调队列优化)最详细题解
- hdu 3401 Trade (单调队列优化)
- HDU3401 Trade (动态规划+单调队列)
- 图解Window下Telnet与远程桌面登陆工具使用
- Jquery 仿淘宝京东多条件筛选 可自行结合ajax加载
- 关于AndroidRuntime: FATAL EXCEPTION: GLThread 10 java.lang.IllegalArgumentException问题
- SimpleAdapter
- (转)android 判断当前application 是在前台还是在后台
- 动态规划(DP) 之优先队列优化 HDOJ 3401Trade
- (二)新建dll以及静态调用dll
- 字符串全排列算法
- eclipse通过wifi连接android进行调试
- CSS、JavaScript开发优秀网站的10款工具
- 相机标定MATLAB工具箱
- 全选复选框和取消所有复选框 jquery全选复选框 js全选复选框
- (三)新建dll以及动态调用dll
- 再说final变量