Codeforces 623 B. Array GCD
2016-02-06 14:04
344 查看
传送门:
http://codeforces.com/contest/623/problem/B
题意:
有n个数,你可以花费i*a去删除长度i的线段,也可以花费B去让一个数+-1,但是删除操作只能进行一次,+-1对一个数也只能操作一次
并且删除操作不能删除所有的数
问你最小花费多少,可以使得剩下的数的gcd不等于1
题解:
很显然,因为不能删除完,所以必然第一个数和最后一个数会剩下来
所以我们暴力枚举第一个数和最后一个数的质因子就好了
然后开始跑dp
dp[i][0,1,2] 分别表示子串未开始,开始了,取完了的状态下达到目标所需要的最低花费,然后dp就可以了!!
code:
附上另一种写法(原理一样,只不过就用了3个状态去表示):
并且体会一下vector的去重方法
http://codeforces.com/contest/623/problem/B
题意:
有n个数,你可以花费i*a去删除长度i的线段,也可以花费B去让一个数+-1,但是删除操作只能进行一次,+-1对一个数也只能操作一次
并且删除操作不能删除所有的数
问你最小花费多少,可以使得剩下的数的gcd不等于1
题解:
很显然,因为不能删除完,所以必然第一个数和最后一个数会剩下来
所以我们暴力枚举第一个数和最后一个数的质因子就好了
然后开始跑dp
dp[i][0,1,2] 分别表示子串未开始,开始了,取完了的状态下达到目标所需要的最低花费,然后dp就可以了!!
code:
[code]#include <cstdio> #include <algorithm> #include <set> using namespace std; set<int> fac; void factor(int x) { for (int i = 2; i * i <= x; ++i) { if (x % i == 0) { fac.insert(i); while (x % i == 0) x /= i; } } if (x > 1) fac.insert(x); } int n, a, b; int p[1000000]; long long dp[1000001][3]; long long check(int v) { dp[0][0] = 0; dp[0][1] = dp[0][2] = 1e18; for (int i = 0; i < n; ++i) { dp[i + 1][0] = dp[i + 1][1] = dp[i + 1][2] = 1e18; if (p[i] % v == 0) { dp[i + 1][0] = dp[i][0]; dp[i + 1][2] = min(dp[i][1], dp[i][2]); } else if ((p[i] + 1) % v == 0 || (p[i] - 1) % v == 0) { dp[i + 1][0] = dp[i][0] + b; dp[i + 1][2] = min(dp[i][1], dp[i][2]) + b; } dp[i + 1][1] = min(dp[i][0], dp[i][1]) + a; } return min({dp [0], dp [1], dp [2]}); } int main() { scanf("%d %d %d", &n, &a, &b); for (int i = 0; i < n; ++i) scanf("%d", &p[i]); for (int u: {-1, 0, 1}) for (int v: {p[0], p[n - 1]}) factor(u + v); long long ans = 1e18; for (int v: fac) ans = min(ans, check(v)); printf("%I64d\n", ans); return 0; }
附上另一种写法(原理一样,只不过就用了3个状态去表示):
并且体会一下vector的去重方法
[code]#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <algorithm> #include <vector> using namespace std; typedef long long LL; const LL INF=10000000000000000LL; const int N=1000000+10; vector<int>V; int n,x ; LL a,b; void MakePrime(int x) { int Max=int(sqrt((double)x)); for (int i=2;i<=Max;i++){ if (x%i==0){ V.push_back(i); while (x%i==0)x/=i; } } if (x>1)V.push_back(x); } LL Solve(int p) { LL s1=0,s2=0,s3=0; for (int i=1;i<=n;i++){ LL Now=INF; if (x[i]%p==0)Now=0; else if ((x[i]-1)%p==0 || (x[i]+1)%p==0)Now=b; s1=min(s1+Now,INF);s2=min(s1,s2+a);s3=min(s2,s3+Now); } return s3; } int main() { cin>>n>>a>>b; for (int i=1;i<=n;i++)scanf("%d",&x[i]); for (int i=-1;i<=1;i++){ MakePrime(x[1]+i); MakePrime(x +i); } sort(V.begin(),V.end()); V.erase(unique(V.begin(),V.end()),V.end()); LL Ans=INF; for (int i=0;i<V.size();i++){ Ans=min(Ans,Solve(V[i])); } cout<<Ans<<endl; return 0; }
相关文章推荐
- PHP限制HTML内容中图片必须是本站的方法
- spring 4.x + struts 2.x + mybatis 3.x - getting started
- 怎么用c#编写浏览器或者执行javascript代码?
- 哈理工OJ 2171 做菜【思维】
- cocos2d-x 3.1 集成 云风pbc
- 我放浪形骸的2016
- springmvc(十五)springmvc注解开发-springmvc参数绑定-list绑定
- 51单片机延时计算
- 基于MFC简单图片裁剪工具
- android Notification 的使用
- Android开发学习之路--UI之基本布局
- Android开发学习之路--UI之基本布局
- 数据库查询、存储
- HDU 3549 Flow Problem(最大流入门)
- nyoj484The famouse clock
- HDOJ 1040 As Easy As A+B
- Eclipse错误提示:The project was not built since its build path is incomplete. Cannot find the class file
- sublime text 2/3 快捷键汇总
- echarts 应用数个样例
- 嵌入式audio基础(七)分析