D1/D2. Painting the Array I/II
题目链接:https://codeforces.ml/contest/1480/problem/D1
题意:在给定数组中选出两段子序列 (每个元素都要选择)要求相邻元素没有一样的,问两段子序列长度和最长为多少
思路:贪心 只需要维护每一段的末尾元素
对于每个元素 如果两段子序列末尾元素只有一个不同 那就接在不同的末尾,如果都相同,那就随便接一个,如果两个都不同
那么就接在 末尾离下一个相同元素更近的那个 这样可以将下次减少贡献的可能降低
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e5+10; 4 const int mod=1e9+7; 5 #define ll long long 6 #define pi pair<int,int> 7 #define fi first 8 #define sc second 9 #define pb push_back 10 int a[maxn],p[maxn],nxt[maxn]; 11 12 13 14 int main() 15 { 16 ios::sync_with_stdio(0); 17 cin.tie(0); 18 int n; 19 cin>>n; 20 for(int i=1;i<=n;i++) cin>>a[i]; 21 for(int i=0;i<=n;i++) p[i]=n+1; 22 for(int i=n;i>=0;i--) 23 { 24 nxt[i]=p[a[i]]; 25 p[a[i]]=i; 26 } 27 int x=0,y=0; 28 int ans=0; 29 for(int i=1;i<=n;i++) 30 { 31 if(a[x]!=a[i]&&a[y]==a[i]) 32 x=i,ans++; 33 else if(a[y]!=a[i]&&a[x]==a[i]) 34 y=i,ans++; 35 else if(a[x]==a[i]&&a[y]==a[i]) 36 x=i; 37 else 38 { 39 if(nxt[x]<nxt[y]) 40 x=i; 41 else y=i; 42 ans++; 43 } 44 } 45 cout<<ans<<'\n'; 46 47 48 49 }
题目链接:https://codeforces.ml/contest/1480/problem/D2
题意:同上,问两段子序列长度和最短为多少
思路:贪心, 对于每个元素,如果两段相同,那就随意接,如果只有一个相同,就接在一个上,如果两个都不相同
就接在 末尾离下一个相同元素更远的那个
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e5+10; 4 const int mod=1e9+7; 5 #define ll long long 6 #define pi pair<int,int> 7 #define fi first 8 #define sc second 9 #define pb push_back 10 int a[maxn],p[maxn],nxt[maxn]; 11 12 13 14 int main() 15 { 16 ios::sync_with_stdio(0); 17 cin.tie(0); 18 int n; 19 cin>>n; 20 for(int i=1;i<=n;i++) cin>>a[i]; 21 for(int i=0;i<=n;i++) p[i]=n+1; 22 for(int i=n;i>=0;i--) 23 { 24 nxt[i]=p[a[i]]; 25 p[a[i]]=i; 26 } 27 int x=0,y=0; 28 int ans=0; 29 for(int i=1;i<=n;i++) 30 { 31 if(a[x]==a[i]) x=i; 32 else if(a[y]==a[i]) y=i; 33 else if(nxt[x]<nxt[y]) y=i,ans++; 34 else x=i,ans++; 35 } 36 cout<<ans<<'\n'; 37 38 39 40 }

浙公网安备 33010602011771号