HDU 3401 DP+单调队列

不会做,看别人的代码,想了一天才想明白

原文地址:http://blog.csdn.net/fp_hzq/article/details/7881075


#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;
 }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值