• Codeforces 623B Array GCD


    Array GCD

    最后的序列里肯定有a[1], a[1]-1, a[1]+1, a[n], a[n]-1, a[n]+1中的一个,枚举质因子, dp去check

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ull unsigned long long
    using namespace std;
    
    const int N = 1e6 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-8;
    
    LL n, a, b, tot, ans = INF;
    LL c[N], fac[100], dp[N][3];
    
    void solve(int x) {
        for(int i = 2; i * i < x; i++) {
            if(x % i) continue;
            fac[tot++] = i;
            while(x % i == 0) x /= i;
        }
        if(x > 1) fac[tot++] = x;
        sort(fac, fac + tot);
        tot = unique(fac, fac + tot) - fac;
    }
    
    void calc(int fac) {
        memset(dp, INF, sizeof(dp));
        dp[0][0] = 0;
        for(int i = 0, r1, r2, r3; i < n; i++) {
            r1 = (c[i + 1] - 1) % fac;
            r2 = r1 + 1; if(r2 >= fac) r2 -= fac;
            r3 = r2 + 1; if(r3 >= fac) r3 -= fac;
            if(dp[i][0] < INF) {
                dp[i + 1][1] = min(dp[i + 1][1], dp[i][0] + a);
                if(!r2) dp[i + 1][0] = min(dp[i + 1][0], dp[i][0]);
                else if(!r1 || !r3) dp[i + 1][0] = min(dp[i + 1][0], dp[i][0] + b);
            }
            if(dp[i][1] < INF) {
                dp[i + 1][1] = min(dp[i + 1][1], dp[i][1] + a);
                if(!r2) dp[i + 1][2] = min(dp[i + 1][2], dp[i][1]);
                else if(!r1 || !r3) dp[i + 1][2] = min(dp[i + 1][2], dp[i][1] + b);
            }
            if(dp[i][2] < INF) {
                if(!r2) dp[i + 1][2] = min(dp[i + 1][2], dp[i][2]);
                else if(!r1 || !r3) dp[i + 1][2] = min(dp[i + 1][2], dp[i][2] + b);
            }
        }
        for(int i = 0; i < 3; i++)
            ans = min(ans, dp[n][i]);
    }
    
    int main() {
        scanf("%lld%lld%lld", &n, &a, &b);
        for(int i = 1; i <= n; i++) scanf("%lld", &c[i]);
        for(int i = -1; i <= 1; i++) solve(c[1] + i);
        for(int i = -1; i <= 1; i++) solve(c[n] + i);
        for(int i = 0; i < tot; i++) calc(fac[i]);
        printf("%lld
    ", ans);
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    SDN课程阅读作业(2)
    2019 SDN上机第5次作业
    第01组 Alpha事后诸葛亮
    Windows 7 64位安装cURL
    html 空白汉字占位符&#12288;
    申请一个免费美国手机号码
    搭建网站需要学习什么(转自知乎)
    Eclipse 项目有红感叹号
    CSS字体大小之em,px,百分比
    题目1013:开门人和关门人
  • 原文地址:https://www.cnblogs.com/CJLHY/p/10362487.html
Copyright © 2020-2023  润新知