UVALive 4327 Parade(hdu 2490 Parade)
来源:互联网 发布:厦大吴春明 知乎 编辑:程序博客网 时间:2024/04/30 08:44
单调队列优化的dp,要用到两层单调队列。。做了很久很久。。。原来用long long 运算要比用int慢上很多很多,就是因为我用的longlong 一直超时,改成int就ac了,真是无语啊。。。这题模型挺容易想的,但是数据量超大,肯定不能正常的递推,仔细想想可以发现,其实每一次递推不必用前一层所有满足情况的值去找到该层的最大值,可以用单调队列维护满足条件区间的最大值,这样就可以在O(1)的时间下获得最大值,于是问题就迎刃而解了。
我用的数组模拟的单调队列,写的时候一定要把下标搞清楚,不然会一直wa。dp数组表示的是到达第i层第j个点时的最大值,第一层单调队列维护的是花费时间,因为时间一直是正的,所以直接维护就可以了,然后每次维护满足到达该点的情况的最值用max_val数组来维护,其实这个维护直接用while()维护就可以了,时间复杂度绝对不会超时,当然用二分也可以。事实证明直接维护不比二分慢。。。
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#define LL long long#define CLR(a, b) memset(a, b, sizeof(a))#define SL(a) strlen(a)using namespace std;const int N = 111;const int M = 11111;int dp[N][M];int welc[N][M];int tim[N][M], max_val[M];//用来模拟单调队列。int add[M];/*int B_ser(int l, int r, int key){ int m; while(l <= r) { m = (l + r) >> 1; if(max_val[m] >= key) l = m + 1; else r = m - 1; } return l;}*/int main(){ //freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); int n, m, i, j, l, r, head, tail, t, k, ans; while(scanf("%d%d%d", &n, &m, &k), n + m + k) { CLR(welc, 0);CLR(tim, 0); for(i = 0; i <= n; i ++) { for(j = 1; j <= m; j ++) { scanf("%d", &welc[i][j]); } } for(i = 0; i <= n; i ++) { tim[i][0] = 0; for(j = 1; j <= m; j ++) { scanf("%d", &tim[i][j]); tim[i][j] += tim[i][j - 1]; } } CLR(dp, 0); for(i = 0; i <= n; i ++) { add[0] = head = l = 0; tail = -1; r = 0; while(r <= m) { while(tim[i][r] - tim[i][l] <= k && r <= m) { while(tail >= head && max_val[tail] < dp[i][r] - add[r]) tail --; //tail = B_ser(head, tail, dp[i][r] - add[r]); max_val[++ tail] = dp[i][r] - add[r]; dp[i + 1][r] = max_val[head] + add[r]; add[r + 1] = add[r] + welc[i][r + 1]; r ++; } if(r > m) break; while(tim[i][r] - tim[i][l] > k && l <= r) { if(dp[i][l] - add[l] == max_val[head]) head ++; l ++; } } add[m] = 0; tail = -1;head = 0; l = r = m; while(l >= 0) { while(tim[i][r] - tim[i][l] <= k && l >= 0) { while(tail >= head && max_val[tail] < dp[i][l] - add[l]) tail --; //tail = B_ser(head, tail, dp[i][l] - add[l]); max_val[++ tail] = dp[i][l] - add[l]; dp[i + 1][l] = max(dp[i + 1][l], max_val[head] + add[l]); if(l)add[l - 1] = add[l] + welc[i][l]; l --; } if(l < 0) break; while(tim[i][r] - tim[i][l] > k && l <= r) { if(dp[i][r] - add[r] == max_val[head]) head ++; r --; } } } ans = 0; for(i = 0; i <= m; i ++) ans = max(ans, dp[n + 1][i]); printf("%d\n", ans); }}
- UVALive 4327 Parade(hdu 2490 Parade)
- UVALive 4327 Parade
- HDU - 2490 Parade
- HDU-2490-Parade
- Parade。。。。
- Parade
- UVALive - 4327 Parade DP + 优先队列
- Olympic Parade UVALive
- Hdu-4749 Parade Show
- UVaLive 4327 | POJ 3926 - Parade (单调队列优化DP)
- Live Archive 4327 Parade
- hdu 4749 Parade Show ( kmp )
- HDU 3687 National Day Parade
- hdu 4749 Parade Show KMP
- hdu 3687 National Day Parade
- HDU 3687 National Day Parade
- hdu 4749 Parade Show(KMP)
- hdu 3687 National Day Parade
- 路由器连接路由器设置方法
- JVM的常用参数
- #include< >和#include“ ”的区别
- [Android实例] Handler+ExecutorService(线程池)+MessageQueue模式+缓存模式
- android-摇一摇实例
- UVALive 4327 Parade(hdu 2490 Parade)
- POJ2823_Slidingwindow_solution
- redis 持久化与备份策略
- jsp学习之旅的错误记录01
- 晨会如何更好的描述自己的工作
- jQuery 双击事件(dblclick)时,不触发单击事件(click)
- starting with mongodb 2013/8/23
- 北大 ACM 1007 DNA Sorting
- 【C/C++】内存分配函数:malloc,calloc,realloc,_alloca