• Bzoj4893 项链分赃


    Time Limit: 4 Sec  Memory Limit: 128 MB
    Submit: 89  Solved: 60

    Description

    有一串长度为n的项链,上面有红绿蓝三种颜色的珠子,每种颜色的珠子数目都是偶数,现在要你把它切几刀分成
    若干段,把其中一些段分给海盗1,剩余的段分给海盗2,要求两个海盗分得的每种颜色的珠子数量都相同,请输出
    最少需要切多少刀。
     

    Input

    第一行一个整数n,表示项链的长度。
    第二行n个0~2的整数,分别表示红绿蓝三种颜色。
     

    Output

    一行一个整数,为最少切多少刀。
     

    Sample Input

    6
    0 2 2 1 0 1

    Sample Output

    2
    样例解释:切两刀,分成{0,2},{2,1,0},{1}三份,第二份给海盗1,剩下给海盗2即可。

    HINT

    n<=100000

    Source

    巨大脑洞题

    (开始以为“项链”是环,过了一阵子测样例才发现是链)

    这题看上去不可做啊……

    切一刀好说,累计前缀和,扫一遍就行;

    切两刀好说,维护一个队列,队列里每种颜色数不超过一半,扫一遍就行;

    切三刀……怎么搞啊?

    试图乱搞,假设答案不是1就是2,WA掉了。

    继续乱搞,假设答案不是1就是2就是3,A掉了。

    卧槽?咋回事儿啊.jpg

    然后去看了出题人的证明 http://www.cnblogs.com/juruolty/p/6806029.html

    脑洞……超大啊

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<cmath>
     6 using namespace std;
     7 const int mxn=100010;
     8 int read(){
     9     int x=0,f=1;char ch=getchar();
    10     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    11     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    12     return x*f;
    13 }
    14 int n;
    15 int smm[mxn][3];
    16 int now[3];
    17 int a[mxn];
    18 int main(){
    19     int i,j,x;
    20     n=read();
    21     for(i=1;i<=n;i++){
    22         x=read();a[i]=x;
    23         smm[i][0]=smm[i-1][0];
    24         smm[i][1]=smm[i-1][1];
    25         smm[i][2]=smm[i-1][2];
    26         ++smm[i][x];
    27     }
    28     for(i=1;i<=n;i++){
    29         for(j=0;j<=2;j++){
    30             if((smm[i][j]<<1)!=smm[n][j])break;
    31         }
    32         if(j==3){
    33             printf("1
    ");
    34             return 0;
    35         }
    36     }
    37     int hd=1;
    38     for(i=1;i<=n;i++){
    39         ++now[a[i]];
    40         for(j=0;j<=2;j++){
    41             while(hd<=i && (now[j]<<1)>smm[n][j] )now[a[hd]]--,hd++;
    42         }
    43         if( ((now[0]<<1)==smm[n][0]) &&
    44             ((now[1]<<1)==smm[n][1]) &&
    45             ((now[2]<<1)==smm[n][2]) ){
    46                 printf("2
    ");
    47                 return 0;
    48             }
    49     }
    50     printf("3
    ");
    51     return 0;
    52 }
  • 相关阅读:
    bzoj 2259 [Oibh]新型计算机 ——最短路(建图)
    bzoj 4555 [Tjoi2016&Heoi2016]求和——NTT+第二类斯特林数
    NOIp2018 D2T3 defense——树上倍增
    bzoj 3456 城市规划——分治FFT / 多项式求逆 / 多项式求ln
    洛谷 4721 【模板】分治 FFT——分治FFT / 多项式求逆
    bzoj 3625(CF 438E)The Child and Binary Tree——多项式开方
    洛谷 P3377 模板左偏树
    CF 1016 C —— 思路
    洛谷 P3806 点分治模板
    洛谷 P4149 [ IOI 2011 ] Race —— 点分治
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6858751.html
Copyright © 2020-2023  润新知