#贪心+等差/比数列<序列><嚎叫响彻在贪婪的厂房>
1 #include<cstdio>
2 #include<iostream>
3 #include<map>
4 #define MAXN 100010
5 #define ll long long
6 #define maxn(a,b) (a)>(b)?(a):(b)
7 #define minn(a,b) (a)<(b)?(a):(b)
8 using namespace std;
9 inline ll read(){
10 ll s=0;
11 char ch=getchar();
12 while(ch<'0'||ch>'9')ch=getchar();
13 while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();
14 return s;
15 }
16 map<ll,bool>h;
17 ll dp[MAXN],g[MAXN];
18 ll rn[MAXN],n;
19 ll ans=1;
20 inline ll gcd(ll a,ll b){
21 return b?gcd(b,a%b):a;
22 }
23 inline ll get_g(ll a,ll b){
24 if(a==b)return false;
25 if(!a||!b)return false;
26 ll lin;
27 if(a<b)swap(a,b);
28 lin=a/b;
29 if(lin*b!=a)return false;
30 return lin;
31 }
32 bool pd(ll a,ll b){
33 if(a==b)return true;
34 if(!get_g(a,b))return false;
35 ll tmp;
36 while(1){
37 if(a<b)swap(a,b);
38 if(b==1)return true;
39 if(gcd(a,b)!=b){
40 return false;
41 }
42 a/=b;
43 }
44 return true;
45 }
46 int main(){
47 // freopen("da.in","r",stdin);
48 n=read();
49 for(int i=1;i<=n;++i)rn[i]=read();
50 ans=1;
51 ll llen=1;
52 bool cong=0;
53 for(int i=1;i<=n;++i){
54 if(!cong){
55 llen=1;
56 cong=1;
57 continue;
58 }
59 if(rn[i]!=rn[i-1]){
60 ans=maxn(ans,llen);
61 cong=0;
62 llen=0;
63 --i;
64 continue;
65 }
66 ++llen;
67 ans=maxn(llen,ans);
68 }
69 ans=maxn(ans,llen);
70 for(int i=1;i<n;++i){
71 h.clear();
72 int r=i+1;
73 g[r]=get_g(rn[r-1],rn[r]);
74 if(!g[r]){
75 continue;
76 }
77 dp[r]=2;
78 h[rn[r]]=true;
79 h[rn[r-1]]=true;
80 ans=maxn(ans,dp[r]);
81 for(r=i+2;r<=n;++r){
82 g[r]=get_g(rn[r-1],rn[r]);
83 if(h[rn[r]])break;
84 if(!g[r]){
85 break;
86 }
87 if(!pd(g[r],g[r-1])){
88 break;
89 }
90 h[rn[r]]=true;
91 g[r]=maxn(g[r],g[r-1]);
92 dp[r]=dp[r-1]+1;
93 ans=maxn(dp[r],ans);
94 }
95 }
96 printf("%lld\n",ans);
97 }
1 #include<cstdio>
2 #include<cstring>
3 #include<map>
4 #include<cmath>
5 #include<iostream>
6 #define reg register
7 #define INF 0x7fffffff
8 #define int long long
9 using namespace std;
10 inline int minn(int a,int b){return a<b?a:b; }
11 inline int maxn(int a,int b){return a>b?a:b; }
12 inline int read(){
13 int s=0,w=0;char ch=getchar();
14 while(ch<'0'||ch>'9')w|=(ch=='-'),ch=getchar();
15 while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();
16 return w?-s:s;
17 }
18 #define kd (read())
19 const int MAXN=100010;
20 int N;
21 int rn[MAXN];
22 int gcd(int a,int b){return b?gcd(b,a%b):a; }
23 int ans=0;
24 map<int ,bool >mp;
25 signed main(){
26 //freopen("da.in","r",stdin);
27 N=kd;
28 for(reg int i=1;i<=N;++i)rn[i]=kd;
29 bool xj=1;
30 int gx=0;
31 int pos=1;
32 while(pos<=N){
33 if(xj){
34 mp.clear();
35 ++ans;
36 if(pos==N)break;
37 if(rn[pos]!=rn[pos+1]&&abs(rn[pos]-rn[pos+1])!=1){
38 gx=maxn(rn[pos+1]-rn[pos],rn[pos]-rn[pos+1]);
39 mp[rn[pos]]=1;
40 mp[rn[pos+1]]=1;
41 xj=0;pos=pos+2;
42 }
43 else xj=1,++pos;
44 }
45 else{
46 int tt=gcd(maxn(rn[pos]-rn[pos-1],rn[pos-1]-rn[pos]),gx);
47 if(tt>1&&!mp[rn[pos]])gx=tt,mp[rn[pos]]=1,++pos;
48 else xj=1;
49 }
50 }
51 printf("%lld\n",ans);
52 }
先丢两个代码,两道题还是很像的。序列里的一个点肯定是尽量和其他的合并,如果考虑从前往后扫,那么这个点能和前面的合并(条件满足情况下)一定不吃亏,所以硬扫O(N)。
不过,细节还是挺多的,比如数列中一定不能有相同的数。还有<嚎叫响彻在贪婪的厂房>中对公差大于1的要求
while(pos<=N){
if(xj){
mp.clear();
++ans;
if(pos==N)break;
if(rn[pos]!=rn[pos+1]&&/*/*/abs(rn[pos]-rn[pos+1])!=1/*/*/){//判公差不为1
gx=maxn(rn[pos+1]-rn[pos],rn[pos]-rn[pos+1]);
mp[rn[pos]]=1;
mp[rn[pos+1]]=1;
xj=0;pos=pos+2;
}
else xj=1,++pos;
}
else{
int tt=gcd(maxn(rn[pos]-rn[pos-1],rn[pos-1]-rn[pos]),gx);
if(tt>1&&!mp[rn[pos]])gx=tt,mp[rn[pos]]=1,++pos;
else xj=1;
}
}
不够细心鸭!