fzu 2216 The Longest Straight 二分

来源:互联网 发布:jessica整容分析知乎 编辑:程序博客网 时间:2024/06/04 19:51

题目链接

http://acm.fzu.edu.cn/problem.php?pid=2216

题意

给出n张牌,每张牌有个数值,n张牌中最大的值为m。值为0的牌可以代替任意值,问可以凑出最长顺子的长度是多少。

思路

用dp[i] 表示从1到j需要填0的个数
dp[j] - d[i] 表示 i+1 到 j需要填0的个数
然后mlogm 枚举

#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<vector>#include<string>#include<queue>#include<stack>#include<set>#include<map>#define ll long longusing namespace std;const int INF = ( 2e9 ) + 2;const ll maxn = 1e5+10;int dp[maxn];bool vis[maxn];int main(){    int T;    scanf("%d",&T);    while(T--)    {        memset(vis,0,sizeof(vis));        memset(dp,0,sizeof(dp));        int n,m,temp,z=0;        scanf("%d%d",&n,&m);        for(int i=0;i<n;i++)        {            scanf("%d",&temp);            if(temp)            vis[temp]=1;            else            z++;        }        // dp[j]  表示从1到j需要填0的个数        // dp[j] - d[i]  i+1 到 j需要填0的个数         for(int i=1;i<=m;i++)        {            if(vis[i])            dp[i]=dp[i-1];            else            dp[i]=dp[i-1]+1;        }        int ans=-INF;        for(int i=0;i<m;i++)        {            int l=i,r=m;            while(l<=r)            {                int mid=(l+r)>>1;                if(dp[mid]-dp[i]>z)                r=mid-1;                else                l=mid+1;            }            ans=max(ans,r-i);        }        printf("%d\n",ans);    }}
原创粉丝点击