zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    升级2010
    如何修改MSSQL的用户名
    减小delphi体积的方法
    Delphi调用大漠插件示例
    Delphi 7升级到XE2的字符串问题
    MSSQL 清空数据库中表的数据
    MSSQL 2008 密钥
    springboot 2.1.4 多数据源配置
    springboot 数据库连接 解决驼峰命名问题
    Flask 热更新
  • 原文地址:https://www.cnblogs.com/AC-Phoenix/p/4467017.html
Copyright © 2011-2022 走看看