codeforces 624d 623b Array GCD ★ ★

来源:互联网 发布:python sort函数 编辑:程序博客网 时间:2024/05/18 21:12

题意:有两种操作,每种只能用一次,第一种对于一段连续区间进行移除(不能全删完),代价是长度*a,第二种是对于一些数进行+1或者-1,使得最后的剩余的最大公约数大于1

思路:由于不能全删完,所以至少会有一个数留着,这个数肯定会是头一个或最后一个,最大公约数肯定是在选中的这个数最后状态中的一个约数,而我们只要先枚举这个数是多少(一共6种),然后枚举他的素因子,用dp顺推即可。

#include <set>#include <map>#include <stack>#include <queue>#include <deque>#include <cmath>#include <vector>#include <string>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define L(i) i<<1#define R(i) i<<1|1#define INF  0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-9#define maxn 1000100#define MOD 1000000007long long dp[maxn][3];int val[maxn];long long a,b;int prime[maxn];int vis[maxn];int n,cnt,fac[maxn];void init(){    cnt = 0;    for(int i = 2; i < maxn; i++)    {        if(!vis[i])            prime[cnt++] = i;        for(int j = 0; j < cnt && prime[j]*i < maxn; j++)        {            vis[prime[j]*i] = 1;            if(i%prime[j] == 0)                break;        }    }}long long solve(int st,int ed,int v){    memset(dp,0x3f3f3f3f3f3f3f3f,sizeof(dp));    dp[st-1][0] = 0;    for(int i = st; i <= ed; i++)    {        dp[i][1] = min(dp[i-1][0],dp[i-1][1]) + a;        if(val[i] % v != 0)        {            if((val[i]+1)%v == 0 || (val[i]-1)%v==0)            {                dp[i][0] = dp[i-1][0] + b;                dp[i][2] = min(dp[i-1][1],dp[i-1][2]) + b;            }        }        else        {            dp[i][0] = dp[i-1][0];            dp[i][2] = min(dp[i-1][1],dp[i-1][2]);        }    }    return min(min(dp[ed][0],dp[ed][1]),dp[ed][2]);}int factor(int x){    int tot = 0;    for(int j = 0; j < cnt && x >= prime[j]; j++)    {        if(x%prime[j] == 0)        {            fac[tot++] = prime[j];            while(x%prime[j] == 0)                x /= prime[j];        }    }    if(x != 1)        fac[tot++] = x;    return tot;}int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int t,C = 1;    //scanf("%d",&t);    init();    while(scanf("%d%lld%lld",&n,&a,&b) != EOF)    {        for(int i = 1; i <= n; i++)            scanf("%d",&val[i]);        long long ans = a * (long long)n;        for(int i = -1; i <= 1; i++)        {            long long cost = i == 0?0:b;            int len = factor(val[n]+i);            for(int j = 0; j < len; j++)                ans = min(ans,solve(1,n-1,fac[j])+cost);            len = factor(val[1]+i);            for(int j = 0; j < len; j++)                ans = min(ans,solve(2,n,fac[j])+cost);        }        printf("%lld\n",ans);    }    return 0;}


0 0