您的位置:首页 > 其它

HDU 3401 DP+单调队列

2012-12-05 15:53 295 查看
不会做,看别人的代码,想了一天才想明白

原文地址:/article/2371417.html

#include "stdio.h"

#define M 2001
#define MAX(a, b) ((a)>(b)?(a):(b))

int dp[M][M];
int t, m, w;
int ap, bp, as, bs;
int v[M], p[M];
int l, r;

int main(){
int c, i, j, k, tmp;
freopen("in.txt", "r", stdin);
scanf("%d", &c);
while(c--){
scanf("%d %d %d", &t, &m, &w);
for(i=1; i<=w+1; i++){
scanf("%d %d %d %d", &ap, &bp, &as, &bs);
for(j=0; j<=m; j++){
dp[i][j] = (j<=as)?(-j*ap):-0x7FFFFFFF;
if(i>1) dp[i][j] = MAX(dp[i][j], dp[i-1][j]);
}
}

for(i=w+2; i<=t; i++){
scanf("%d %d %d %d", &ap, &bp, &as, &bs);
k = i-w-1;
l = 0; r = -1;
for(j=0; j<=m; j++){
//dp[k][x]-ap*(j-x) = dp[k][x] + ap*x - ap*j;
//v[l] = dp[k][x] + ap*x; q[l] = x
//dp[i][j] = MAX(..., v[l] - ap*j)
tmp = dp[k][j] + ap*j;
while(l<=r && v[r]<tmp) r--;
v[++r] = tmp;
p[r] = j;
while(l<=r && p[l]+as<j) l++;
dp[i][j] = MAX(dp[i-1][j], v[l] - ap*j);
}
l = 0; r = -1;
for(j=m; j>=0; j--){
//dp[k][x] + bp*(x-j) = dp[k][x] + bp*x -bp*j;
//v[l] = dp[k][x] + bp*x; q[l] = x
//dp[i][j] = MAX(..., v[l] - bp*j);
tmp = dp[k][j] + bp*j;
while(l<=r && v[r]<tmp) r--;
v[++r] = tmp;
p[r] = j;
while(l<=r && p[l]-bs>j) l++;
dp[i][j] = MAX(dp[i][j], v[l] - bp*j);
}
}
printf("%d\n", dp[t][0]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: