• UESTC


    他们oj挂掉啦, 我先保存一下代码。。。

    直接dp复杂度, n * 100 * 100, 我们可以将前一个人的信息丢进单调队列中去,可以优化成n * 100;

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define pii pair<int,int>
    #define piii pair<int, pair<int,int> >
    
    using namespace std;
    
    const int N = 5e4 + 7;
    const int M = 10 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-6;
    
    int n, c, head1, head2, rear1, rear2;
    int sk1[N], sk2[N], a[N], dp[N][101];
    
    void init() {
        for(int i = 1; i <= n; i++) {
            for(int j = 0; j <= 100; j++) {
                dp[i][j] = inf;
            }
        }
        head1 = head2 = 0;
        rear1 = rear2 = 0;
    }
    int main() {
        while(scanf("%d%d", &n, &c) != EOF) {
    
            init();
            for(int i = 1; i <= n; i++) {
                scanf("%d", &a[i]);
            }
    
            for(int j = a[1]; j <= 100; j++) {
                dp[1][j] = (j - a[1]) * (j - a[1]);
            }
    
            for(int i = 2; i <= n; i++) {
    
                rear1 = rear2 = 0;
                head1 = head2 = 0;
    
                for(int j = 0; j <= 100; j++) {
    
                    while(head1 < rear1 && dp[i - 1][j] + c * j < dp[i - 1][sk1[rear1 - 1]] + c * sk1[rear1 - 1]) rear1--;
                    sk1[rear1++] = j;
                }
    
                for(int j = 100; j >= 0; j--) {
    
                    while(head2 < rear2 && dp[i - 1][j] - c * j < dp[i - 1][sk2[rear2 - 1]] - c * sk2[rear2 - 1]) rear2--;
                    sk2[rear2++] = j;
                }
    
                for(int j = a[i]; j <= 100; j++) {
                    while(head1 < rear1 && sk1[head1] < j) head1++;
                    if(head1 < rear1) dp[i][j] = dp[i - 1][sk1[head1]] + c * sk1[head1] + (j - a[i]) * (j - a[i]) - c * j;
                }
    
                for(int j = 100; j >= a[i]; j--) {
                    while(head2 < rear2 && sk2[head2] > j) head2++;
                    if(head2 < rear2) dp[i][j] = min(dp[i][j], dp[i - 1][sk2[head2]] - c * sk2[head2] + (j - a[i]) * (j - a[i]) + c * j);
                }
            }
    
            int ans = inf;
            for(int j = a[n]; j <= 100; j++) {
                ans = min(ans, dp[n][j]);
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    /*
    */
  • 相关阅读:
    多列转两列(Power Query)
    多簿多表合并(Power Query)
    高亮显示指定内容
    价格段公式
    按日期段计算平均销量
    Filter、Unique如何跳过隐藏行
    人民币填空
    按换行符拆分(Power Query)
    添加分类汇总小计行(Power Query)
    添加累计列(Power Query)
  • 原文地址:https://www.cnblogs.com/CJLHY/p/9173966.html
Copyright © 2020-2023  润新知