戳这里看题目吧!

题目大意:给你一个长度为n(2<=n<=5000)的序列,没有重复的数字,序列中每个元素满足(0<=numi<=1e9)。求一个最长的数列满足差分值相同(除n=2外,可以看成等差数列)。输出这个最大长度。

算法梗概:DP。看了几篇博客都说算是个板子套路DP题。在做的时候也想到了DP,但是没找对状态。

     另外可以用其他算法来做这道题,后面慢慢补。先给出DP算法的代码和思路。

 #include<cstdio>
#include<algorithm>
const int maxn = 5e3 + ;
int dp[maxn][maxn],n,num[maxn];
int main()
{
scanf("%d",&n);
for(int i=;i<=n;++i){
scanf("%d",num+i);
for(int j=;j<=n;++j){
dp[i][j] = ;
}
}
std::sort(num+,num++n);
int ans = ;
for(int i=;i<=n-;++i){
int pre = i - ;
for(int j=i+;j<=n;++j){
  ///令d=num[j] - num[i],因为序列是递增的,所以num[i] - num[pre]在pre刚开始不满足条件时大于d,在pre刚好满足条件时等于d,继续遍历则小于d,后来的遍历是无意义的所以跳出即可
  while(pre > && num[j] - num[i] > num[i] - num[pre]) pre--;
  if(pre==) break;
  else if(pre > && num[j] - num[i] == num[i] - num[pre]) dp[i][j] = std::max(dp[i][j],dp[pre][i]+);
  ans = std::max(ans,dp[i][j]);
}
}
printf("%d\n",ans);
return ;
}

DP思路:dp[i][j]表示已下标i,j(i<j)为结尾两个元素的一个子序列的长。枚举i,以i+1开始向后遍历j,这样对于每对i,j我们可以求出他们的差,以这个差为标准,从i-1开始向前遍历记为pre,直到找到的pre和i,j满足num[j] - num[i] == num[i] - num[pre]。如果找到这样的num[pre]更新dp[i][j]即可。

状态转移方程:dp[i][j] = max(dp[i][j],dp[pre][i]+1)


直接用用等差数列的通项公式来暴力

 #include <cstdio>
#include <algorithm>
#include <set>
using namespace std;
const int maxn = 5e3+;
int num[maxn],n;
set<int> se;
int main()
{
scanf("%d",&n);
for(int i = ; i<=n; ++i)
{
scanf("%d",num+i);
se.insert(num[i]);
}
sort(num+,num+n+);
int ans = ,d,k;
for(int i=;i<=n;++i)
{
for(int j=i+;j<=n;++j)
{
k = ,d = num[j] - num[i];
if(!se.count(num[i] + ans*d)) continue;
while(se.count(num[i] + k*d)) k++;
ans = max(ans,k);
}
if(ans==n) break;
}
printf("%d\n",ans);
return ;
}

核心代码:

     k = ,d = num[j] - num[i];
if(!se.count(num[i] + ans*d)) continue;
while(se.count(num[i] + k*d)) k++;
ans = max(ans,k);

暴力思路:ak = a1 + (k-1)d;

     两层for循环来枚举a1和d,对于每对<a1,d>,枚举k来得到一个ak,判断ak是不是存在在序列中,存在继续枚举,否则更新答案。

请注意!!!  if(!se.count(num[i] + ans*d)) continue; 这行代码的作用,对于你已经更新到的答案ans,如果num[i] + ans*d都不存在,那么无法更新答案,所以跳过这层循环。

没有这行代码会TLE在test 57或者test 58,做题就死在了这里了。


还有些同学用了二分函数,其实和暴力的核心思想差不多,用二分函数优化很多,这里只给代码,不解释了如果暴力看懂了这个也就懂了

 #include<cstdio>
#include<algorithm>
const int maxn = 5e3 + ;
int dp[maxn][maxn],n,num[maxn];
int main()
{
scanf("%d",&n);
for(int i=;i<=n;++i) scanf("%d",num+i);
std::sort(num+,num++n); int ans = ,res,d,pos;
for(int i=;i<=n-;++i){
for(int j=i+;j<=n;++j){
d = num[j] - num[i];
res = ;
pos = std::lower_bound(num+j+,num+n+,num[i]+ans*d) - num;
if(num[pos]!=num[i]+ans*d) continue;
for(int k=j;k<=n-;){
pos = std::lower_bound(num+k+,num+n+,num[k]+d) - num;
if(num[pos]==num[k]+d){
k = pos;
res++;
}
else break;
}
ans = std::max(ans,res);
}
}
printf("%d\n",ans);
return ;
}

This’s all!如有错误,请评论指正谢谢!!

Gym 102082B : Arithmetic Progressions的更多相关文章

  1. [Educational Codeforces Round 16]D. Two Arithmetic Progressions

    [Educational Codeforces Round 16]D. Two Arithmetic Progressions 试题描述 You are given two arithmetic pr ...

  2. Dirichlet's Theorem on Arithmetic Progressions 分类: POJ 2015-06-12 21:07 7人阅读 评论(0) 收藏

    Dirichlet's Theorem on Arithmetic Progressions Time Limit: 1000MS   Memory Limit: 65536K Total Submi ...

  3. 洛谷P1214 [USACO1.4]等差数列 Arithmetic Progressions

    P1214 [USACO1.4]等差数列 Arithmetic Progressions• o 156通过o 463提交• 题目提供者该用户不存在• 标签USACO• 难度普及+/提高 提交 讨论 题 ...

  4. POJ 3006 Dirichlet's Theorem on Arithmetic Progressions (素数)

    Dirichlet's Theorem on Arithmetic Progressions Time Limit: 1000MS   Memory Limit: 65536K Total Submi ...

  5. poj 3006 Dirichlet's Theorem on Arithmetic Progressions【素数问题】

    题目地址:http://poj.org/problem?id=3006 刷了好多水题,来找回状态...... Dirichlet's Theorem on Arithmetic Progression ...

  6. (素数求解)I - Dirichlet&#39;s Theorem on Arithmetic Progressions(1.5.5)

    Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit cid=1006#sta ...

  7. USACO 1.4 Arithmetic Progressions

    Arithmetic Progressions An arithmetic progression is a sequence of the form a, a+b, a+2b, ..., a+nb ...

  8. Educational Codeforces Round 16 D. Two Arithmetic Progressions (不互质中国剩余定理)

    Two Arithmetic Progressions 题目链接: http://codeforces.com/contest/710/problem/D Description You are gi ...

  9. 等差数列Arithmetic Progressions题解(USACO1.4)

    Arithmetic Progressions USACO1.4 An arithmetic progression is a sequence of the form a, a+b, a+2b, . ...

随机推荐

  1. 解决让刷新页面时不提示 "重试或取消”对话框

    如果刷新一个已经提交过的页面时,系统总是会提示一个 "重试或取消”的对话框.,如果是一个普通的页面,好象也无所谓,有就有,大不了多点一下.但是当我们是在子窗体中刷新父窗体时,就显得有点多余了 ...

  2. 8条关于Web前端性能的优化建议

    一般网站优化都是优化后台,如接口的响应时间.SQL优化.后台代码性能优化.服务器优化等.高并发情况下,对前端web优化也是非常重要的. 下面说说几种常见的优化措施. 1.HTML CSS JS位置 一 ...

  3. SpringBoot入门简介

    SpringBoot诞生的背景 所有软件行业里面,如果要说商用体系,排在第一位的永远是java,因为java的体系丰富,支持度高,安全性也高 但是我们所有的开发者也不得不去忍受Java中的以下痛苦 举 ...

  4. sublime text 3安装Anaconda插件之后写python出现白框

    sublime test 3安装anaconda插件之后写python代码会出现白框,这是应为anaconda自带了pep8语法检查, 有一些是语法错误,能够检查出来还是能有用的.但有一些不过是一些代 ...

  5. python 大小写转换函数

    capitalize() 首字母大写,其余全部小写 upper() 全转换成大写 lower() 全转换成小写 title()  标题首字大写,如"i love python".t ...

  6. 62.Longest Valid Parentheses(最长的有效括号)

    Level:   Medium 题目描述: Given a string containing just the characters '(' and ')', find the length of ...

  7. 使用 lombok 简化代码

    使用前的准备 1.Lombok 是一种 Java™ 实用工具,可用来帮助开发人员消除 Java 的冗长,尤其是对于简单的 Java 对象(POJO).它通过注解实现这一目的.  <1>添加 ...

  8. elasticsearch 中的Multi Match Query

    在Elasticsearch全文检索中,我们用的比较多的就是Multi Match Query,其支持对多个字段进行匹配.Elasticsearch支持5种类型的Multi Match,我们一起来深入 ...

  9. signal - 有效信号的清单

    描述 (DESCRIPTION) 下面 列出 Linux 支持的 信号. 某些 信号 依赖于 体系结构(architecture). 首先, POSIX.1 描述了 下列 信号. 信号 值 动作 说明 ...

  10. Ansible --05 ansible jinja2

    ansible jinja2 什么是jinjia2模板 jinjia2是Python的全功能模块引擎 Jinjia2与Ansible的关系 Ansible通常会使用jinjia2模板来修改被管理主机的 ...