当前位置:   article > 正文

Codeforces Round #700 (Div. 2) D1. Painting the Array I(暴力+后缀)

Codeforces Round #700 (Div. 2) D1. Painting the Array I(暴力+后缀)

 

 有 n 个数,可以将他们分成 2 组,但是相对顺序不可以被打乱,在每一组中相邻的多个相同的元素 a,必须合成为一个元素 a,问如何构造这两组,使得元素数量最多

题目翻译的可能不够清楚,建议读懂原题。

感觉这应该是一道 dp 的题目,但是却没有用 dp 来解

如样例 1 所示,预处理得  1(2) 2(2) 3(3) 其中括号内为元素的数量,括号前为元素的大小

这样很明显两组分别为 1 2 3 和 1 2 3,多余的 3 无论放到哪一组中都会被合成,这样算法就很好实现了

但是需要注意,给出数据  1 1 2 3 2 2,最优解应为 1 2 3 2 和 1 2 ,背标红的 2 前面应该有 3 来分割才能达到最优,所以要判断当有单个元素出现时,应该放到那一组里

所以在预处理出 d 数组 ,d[i] 表示后面开始离 i 位置最近的数量>=2 的元素是什么

  1. const int N=1e6+5;
  2. int n,m,t;
  3. int i,j,k;
  4. int a[N];
  5. vector<pii> v;
  6. int d[N];
  7. int main()
  8. {
  9. //IOS;
  10. while(~sd(n)){
  11. for(int i=1;i<=n;i++) sd(a[i]);
  12. int res=1;
  13. for(int i=2;i<=n+1;i++){
  14. if(a[i]!=a[i-1]) v.pb(mp(a[i-1],res)),res=1;
  15. else res++;
  16. }
  17. int len=v.size(),ans=0;
  18. for(int i=len-2;i>=0;i--){
  19. if(v[i+1].sc>=2) d[i]=v[i+1].fr;
  20. else d[i]=d[i+1];
  21. }
  22. int uu=-1,vv=-1;
  23. for(int i=0;i<len;i++){
  24. int x=v[i].sc;
  25. int y=v[i].fr;
  26. if(x>=2){
  27. if(uu!=y && vv!=y) ans+=2,uu=vv=y;
  28. else if(uu!=y || vv!=y) ans++,uu=vv=y;
  29. }
  30. else if(x==1){
  31. if(uu==y && vv==y) continue;
  32. int flag=1;
  33. if(uu!=y && vv!=y && i!=len-1){
  34. int tmp=d[i];
  35. if(tmp==vv) vv=y,ans++,flag=0;
  36. else if(tmp==uu) uu=y,ans++,flag=0;
  37. }
  38. if(!flag) continue;
  39. if(uu!=y) ans++,uu=y;
  40. else if(vv!=y) ans++,vv=y;
  41. }
  42. }
  43. pd(ans);
  44. }
  45. //PAUSE;
  46. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/73214
推荐阅读
相关标签
  

闽ICP备14008679号