HDU 3401 DP+单调队列

来源:互联网 发布:淘宝在哪里评价商品 编辑:程序博客网 时间:2024/06/16 18:47

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

原文地址: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; }


原创粉丝点击