[UESTC 594] 我要长高

Posted kma093

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[UESTC 594] 我要长高相关的知识,希望对你有一定的参考价值。

题目链接:

我要长高

题目分析:

\(dp[i][j]\)表示到第\(i\)个人,他的身高是\(j\)的时候的最小损失,然后得到一个朴素的转移方程
\(dp[i][j] = min(dp[i - 1][k] + abs(k - j) * C + (j - a[i]) ^ 2)\)
把无关的丢到\(min\)外面来
\[ dp[i][j] = \left\ \beginaligned min(dp[i - 1][k] + k * C) - j * C + (j - a[i]) ^ 2 (j < k) \min(dp[i - 1][k] - k * C) + j * C + (j - a[i]) ^ 2 (j > k)\\endaligned \right. \]

直接枚举\(i,j,k\)显然是\(O(n^3)\)的,看到有\(min / max\)考虑怎么单调队列一下
然后发现好像不用单调队列也可以,我们只需要存储当前\(min\)里面那一坨的最小值就可以了

#include<bits/stdc++.h>
#define INF (1000000000 + 7)
#define N (50000 + 10) 
using namespace std;
inline int read() 
    int cnt = 0, f = 1; char c = getchar();
    while (!isdigit(c)) if (c == '-') f = -f; c = getchar();
    while (isdigit(c)) cnt = (cnt << 3) + (cnt << 1) + c - '0'; c = getchar();
    return cnt * f;

int n, C, a[N], dp[N][105];
int gmin, lim, ans;
inline int Pow(int x) return x * x;
int main() 
//  freopen("1.in", "r", stdin);
    while (scanf("%d", &n) != EOF) 
        C = read();
        memset(dp, 0x3f3f, sizeof(dp));
        for (register int i = 1; i <= n; ++i) a[i] = read(), lim = max(lim, a[i]);
        for (register int i = a[1]; i <= lim; ++i) dp[1][i] = Pow(i - a[1]);
        for (register int i = 2; i <= n; ++i) 
            gmin = INF;
            for (register int j = a[i - 1]; j <= lim; ++j) 
                gmin = min(gmin, dp[i - 1][j] - C * j);
                if (j >= a[i]) dp[i][j] = gmin + Pow(j - a[i]) + C * j;
            
            gmin = INF;
            for (register int j = lim; j >= a[i]; --j) 
                gmin = min(gmin, dp[i - 1][j] + C * j);
                if (j >= a[i]) dp[i][j] = min(dp[i][j], gmin + Pow(j - a[i]) - C * j);
            
        
        ans = INF;
        for (register int i = a[n]; i <= lim; ++i) ans = min(ans, dp[n][i]);
        printf("%d\n", ans);
    
    return 0;

以上是关于[UESTC 594] 我要长高的主要内容,如果未能解决你的问题,请参考以下文章

单调队列优化dpuestc 594 我要长高

Rule in UESTC

UESTC 686 BFS

UESTC 1584

UESTC(LCA应用:求两点之间的距离)

分块基础练习 UESTC 1324