UESTC 594 我要长高 dp单调队列优化入门

//其实是个伪单调队列...渣渣刚入门

//戳这里:594

//dp[ i ][ j(现身高) ] = min(    dp[ i ][ k(现身高) ]  + fabs( j(现身高) - k(现身高) ) * C + ( j(现身高) - h[i](原身高) )  *( j(现身高) - h[i](原身高) )     );

观察到可以单调队列优化,O(N * H * H)  —>  O(N * H)

j >= k 时,

dp[ i ][ j ] = min (    dp[ i - 1 ][ k ] + ( j - k ) * C + ( j - h[i] ) * ( j - h[i] )  ); <==>  dp[ i ][ j ] = min (    dp[ i  - 1][ k ]  - k * C    ) +  j * C + ( j - h[i] ) * ( j - h[i] );

j <= k 时,

dp[ i ][ j ] = min (    dp[ i - 1 ][ k ] + ( k - j ) * C + ( j - h[i] ) * ( j - h[i] )  ); <==>  dp[ i ][ j ] = min (    dp[ i - 1 ][ k ]  + k * C    ) -  j * C + ( j - h[i] ) * ( j - h[i] );

将 k 替换成 j, 实现一边维护 dp_pre, 一边求解 dp[ i ][ j ]

 1 #include "bits/stdc++.h"
 2 using namespace std;
 3 int N, C;
 4 int h[50010];
 5 int dp[50010][110];
 6 const int INF = 0x3f3f3f3f;
 7 
 8 int main()
 9 {
10     while(scanf("%d%d", &N, &C) != EOF) {
11         memset(dp, INF, sizeof(dp[0]) * (N + 1)); //直接 memset(dp, INF, sizeof(dp)); 会T...
12         int i;
13         for(i = 1; i <= N; ++i) {
14             scanf("%d", &h[i]);
15         }
16         int j, k;
17         for(j = h[1]; j <= 100; ++j) {
18             dp[1][j] = (j - h[1]) * (j - h[1]);
19         }
20 
21         int dp_pre;
22         for(i = 2; i <= N; ++i) {
23             //k <= j 的情况
24             dp_pre = INF;
25             for(j = h[i - 1]; j <= 100; ++j) {
26                 dp_pre = min(dp_pre, dp[i - 1][j] - j * C);
27                 if(j >= h[i]) {
28                     dp[i][j] = dp_pre + j * C + (j - h[i]) * (j - h[i]);
29                 }
30             }
31 
32             //k >= j 的情况
33             dp_pre = INF;
34             for(j = 100; j >= h[i]; --j) {
35                 if(j >= h[i - 1]) {
36                     dp_pre = min(dp_pre, dp[i - 1][j] + j * C);
37                 }
38                 dp[i][j] = min(dp[i][j], dp_pre - j * C + (j - h[i]) * (j - h[i]));
39             }
40         }
41         int res = INF;
42         for(j = 1; j <= 100; ++j) {
43             res = min(res, dp[N][j]);
44         }
45         printf("%d
", res);
46     }
47 }
原文地址:https://www.cnblogs.com/AC-Phoenix/p/4467017.html