AIM Tech Round (Div. 2) D. Array GCD(dp)

来源:互联网 发布:linux 局域网传文件 编辑:程序博客网 时间:2024/06/05 20:24

题意:

N106,2
1.0M<N,MA
2.0KN,使+11,KB
2,使gcd>1

分析:

,a1,an
gcd109,gcda1,a1±1an,an±1
,log,dp
f[prime][i][3]:=1i,gcdprime,0/,1/,2/,

ans=min{f[prime][N][0],f[prime][N][2]}
O(nlog109)
dp,,

代码:

////  Created by TaoSama on 2016-02-05//  Copyright (c) 2016 TaoSama. All rights reserved.//#pragma comment(linker, "/STACK:1024000000,1024000000")#include <algorithm>#include <cctype>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iomanip>#include <iostream>#include <map>#include <queue>#include <string>#include <set>#include <vector>using namespace std;#define pr(x) cout << #x << " = " << x << "  "#define prln(x) cout << #x << " = " << x << endlconst int N = 1e6 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;int n, A, B;int a[N];long long f[2][3]; //0->removed array, not started, 1->removing, 2->finishedinline void getMin(long long &x, long long y) {    if(x > y) x = y;}int getCost(int i, int p) {    if(a[i] % p == 0) return 0;    else if((a[i] + 1) % p == 0 || (a[i] - 1) % p == 0) return B;    return INF;}void see(int i, int s) {    for(int j = 0; j < 3; ++j)        printf("f[%d][%d]=%I64d\n", i, j, f[s][j]);}long long gao(int p) {    int s = 0;    memset(f[s], 0, sizeof f[s]);    for(int i = 1; i <= n; ++i) {        memset(f[!s], 0x3f, sizeof f[!s]);        int cost = getCost(i, p);        if(cost != INF) {            getMin(f[!s][0], f[s][0] + cost);            getMin(f[!s][2], f[s][2] + cost);        }        getMin(f[!s][1], f[s][0] + A); //start removing        getMin(f[!s][1], f[s][1] + A); //removing        getMin(f[!s][2], f[s][0] + A); //finish right away        getMin(f[!s][2], f[s][1] + A); //finish removing        s = !s;//      if(p == 2) see(i, s);    }    return min(f[s][0], f[s][2]);}int main() {#ifdef LOCAL    freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin);//  freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout);#endif    ios_base::sync_with_stdio(0);    while(scanf("%d%d%d", &n, &A, &B) == 3) {        for(int i = 1; i <= n; ++i) scanf("%d", a + i);        int leave[] = {a[1], a[n]};        long long ans = 1e18;        for(int i = 0; i < 2; ++i) {            for(int d = -1; d <= 1; ++d) {                int x = leave[i] + d;                for(int j = 2; j * j <= x; ++j) {                    if(x % j == 0) {                        ans = min(ans, gao(j));                        while(x % j == 0) x /= j;                    }                }                if(x > 1) ans = min(ans, gao(x));            }        }        printf("%I64d\n", ans);        //        return 0;    }    return 0;}

prefix,suffix
g[i]:=1i | in
f[i]:=1i

代码:

////  Created by TaoSama on 2016-02-05//  Copyright (c) 2016 TaoSama. All rights reserved.//#pragma comment(linker, "/STACK:1024000000,1024000000")#include <algorithm>#include <cctype>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iomanip>#include <iostream>#include <map>#include <queue>#include <string>#include <set>#include <vector>using namespace std;#define pr(x) cout << #x << " = " << x << "  "#define prln(x) cout << #x << " = " << x << endlconst int N = 1e6 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;int n, A, B;int a[N];long long f[N], g[N];long long gao(int p) {    int pos = -1;    for(int i = 1; i <= n; ++i) {        if(a[i] % p == 0) g[i] = g[i - 1];        else if((a[i] + 1) % p == 0 || (a[i] - 1) % p == 0)            g[i] = g[i - 1] + B;        else break;        pos = i;    }    for(int i = 1; i <= n; ++i) {        f[i] = f[i - 1] + A;        if(i <= pos) f[i] = min(f[i], g[i]);    }    g[n + 1] = 0;    long long ret = f[n];    for(int i = n; i; --i) {        if(a[i] % p == 0) g[i] = g[i + 1];        else if((a[i] + 1) % p == 0 || (a[i] - 1) % p == 0)            g[i] = g[i + 1] + B;        else break;        ret = min(ret, f[i - 1] + g[i]);    }    return ret;}int main() {#ifdef LOCAL    freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin);//  freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout);#endif    ios_base::sync_with_stdio(0);    while(scanf("%d%d%d", &n, &A, &B) == 3) {        for(int i = 1; i <= n; ++i) scanf("%d", a + i);        int leave[] = {a[1], a[n]};        long long ans = 1e18;        for(int i = 0; i < 2; ++i) {            for(int d = -1; d <= 1; ++d) {                int x = leave[i] + d;                for(int j = 2; j * j <= x; ++j) {                    if(x % j == 0) {                        ans = min(ans, gao(j));                        while(x % j == 0) x /= j;                    }                }                if(x > 1) ans = min(ans, gao(x));            }        }        printf("%I64d\n", ans);    }    return 0;}
0 0
原创粉丝点击