zoukankan      html  css  js  c++  java
  • Array GCD CodeForces

    大意: 给定序列, 给定常数a,b, 两种操作, (1)任选一个长为$t$的子区间删除(不能全部删除), 花费t*a. (2)任选$t$个元素+1/-1, 花费t*b. 求使整个序列gcd>1的最少花费.

    题目有个限制是不能全部删除, 所以最后一定剩余a[1]或a[n], 暴力枚举a[1]与a[n]的所有素因子即可.

    这场div. 2题目感觉都挺简单的, 但实现起来各种出错...........各种细节还是没考虑好......

    #include <iostream>
    #include <vector>
    #include <cmath>
    #define REP(i,a,n) for(int i=a;i<=n;++i)
    #define pb push_back
    using namespace std;
    typedef long long ll;
    
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    const int N = 1e6+10;
    int n, x, y;
    int a[N], b[N];
    ll ans, dp[3][N];
    
    ll solve(int g, int *a, int n) {
    	memset(dp,0x3f,sizeof dp);
    	dp[0][0]=dp[1][0]=dp[2][0]=0;
    	REP(i,1,n) {
    		dp[0][i] = dp[0][i-1];
    		dp[1][i] = min(dp[0][i-1]+x,dp[1][i-1]+x);
    		dp[2][i] = min({dp[0][i-1],dp[1][i-1],dp[2][i-1]});
    		if (a[i]%g) { 
    			if ((a[i]-1)%g==0||(a[i]+1)%g==0) dp[0][i]+=y,dp[2][i]+=y;
    			else dp[0][i]=dp[2][i]=INF;
    		}
    	}
    	return min(dp[1][n],dp[2][n]);
    }
    
    vector<int> fac(int num) {
    	int mx = sqrt(num+0.5);
    	vector<int> v;
    	REP(i,2,mx) if (num%i==0) {
    		v.pb(i);
    		while (num%i==0) num/=i;
    	}
    	if (num>1) v.pb(num);
    	return v;
    }
    
    void solve(int num, int *a, int n, int tp) {
    	vector<int> g = fac(num);
    	for (auto &&t:g) ans = min(ans, solve(t,a,n)+tp*y);
    }
    
    int main() {
    	scanf("%d%d%d", &n, &x, &y);
    	REP(i,1,n) scanf("%d", a+i);
    	ans = INF;
    	solve(a[1],a+1,n-1,0);
    	solve(a[1]-1,a+1,n-1,1);
    	solve(a[1]+1,a+1,n-1,1);
    	solve(a[n],a,n-1,0);
    	solve(a[n]-1,a,n-1,1);
    	solve(a[n]+1,a,n-1,1);
    	printf("%lld
    ", ans);
    }
    
  • 相关阅读:
    CSS中float与A标签的疑问
    常用的Css命名方式
    div css 盒子模型
    HTML初级教程 表单form
    Redis学习记录(二)
    Redis学习记录(一)
    Java源码——HashMap的源码分析及原理学习记录
    java编程基础——从上往下打印二叉树
    java编程基础——栈压入和弹出序列
    java基础编程——获取栈中的最小元素
  • 原文地址:https://www.cnblogs.com/uid001/p/10797934.html
Copyright © 2011-2022 走看看