JZOJ 4911. 【NOIP2017模拟12.3】人生的叹息

来源:互联网 发布:windows 平板电脑 2017 编辑:程序博客网 时间:2024/06/02 09:20

Description

眨眼间,那额外的一百年时光也过完了,NiroBC走到了人生的尽头。
NiroBC又一次在死亡面前老泪纵横。
NiroBC渴望着那个戴着黑色方框眼镜,方脸,穿着高腰裤的长者能够再一次出现,然而并没有。NiroBC不禁叹息。
我不能就这样死去!人生中还有那么多冲突没有解决!
NiroBC的人生可抽象成一个数列a[1..N],她需要总结自己的人生,便需要给自己的人生划分阶段。现在定义一段人生a[l..r]的冲突值是

这里写图片描述

其中最外面的[]表示,若里面的布尔表达式为真,则值为1,否则值为0。冲突值实际上就是相等的数的对数。

现在NiroBC老眼昏花,她显然不能把人生划分成太多的片段,否则大脑会转不过来。当然每一段的冲突值不能太大,因为NiroBC有精神洁癖。

NiroBC躺在病床上写不了程序,所以她让你写程序把a[1..N]划分成尽量少的片段,且每一段的冲突值都<=K。

Input

共两行。

第一行,正整数N和自然数K。

第二行共N个正整数,第i个正整数表示a[i]。

Sample Input

【输入样例1】

6 0

1 2 1 2 3 1

【输入样例2】

6 1

1 2 1 2 3 1

Output

仅一个整数,表示最小的段数。

Sample Output

【输出样例1】

3

【输出样例2】

2

Data Constraint

对于所有数据,有N<=500,000,K<=N*(N-1)/2,1<=a[i]<=N

对于各个测试点,表中空白格子代表无特殊规定

测试点编号 N a[i] K

1-4 N<=100

5-8 N<=1,000

9-12 1<=a[i]<=2

13-16 K=0

17-20

Hint

【样例解释1】

可以分成(1,2) (1,2,3) (1)

【样例解释2】

可以分成(1,2,1) (2,3,1)

Solution

  • 一眼题,贪心,能选则选!

  • 因为序列越长,冲突值只会越大!

  • 所以能选则尽量选长,以K为界点。

  • 注意数组清零!应该一个个扫序列清零;

  • 因为离散化程度太高,浪费时间,本程序在比赛时分段居然过了~~~

Code

#include<cstdio>#include<cstring>using namespace std;const int N=500001;int ans=1,n,judge;int a[N],bz[N],f[N];long long sum,k;int main(){    scanf("%d%lld",&n,&k);    for(int i=1;i<=n;i++)    {        scanf("%d",&a[i]);        if(!bz[a[i]])        {            bz[a[i]]=1;            judge++;        }    }    memset(bz,0,sizeof(bz));    if(judge<10000)    for(int i=1;i<=n;i++)    {        bool b=false;        for(int j=1;j<=f[0];j++)            if(f[j]==a[i])            {                b=true;                break;            }        if(!b) f[++f[0]]=a[i];        if(sum+bz[a[i]]>k)        {            ans++;            for(int j=1;j<=f[0];j++) bz[f[j]]=0;            f[f[0]=1]=a[i];            bz[a[i]]=1;            sum=0;        }else        {            sum+=bz[a[i]];            bz[a[i]]++;        }    }    else    for(int i=1;i<=n;i++)    {        if(sum+bz[a[i]]>k)        {            ans++;            memset(bz,0,sizeof(bz));            bz[a[i]]=1;            sum=0;        }else        {            sum+=bz[a[i]];            bz[a[i]]++;        }    }    printf("%d",ans);    return 0;}
1 0
原创粉丝点击