根据题意,不难分析出,JATC必须在一段连续递增 1 的数列里面删除元素,否则删除后将不可能复原。
于是,此题贪心的策略就为,选取一段最长的连续递增 1 的数列进行所要的操作。
特别地,要注意满足要求的数列中是否有1,或者1000,可以进行分类讨论,但也可以采取一些方法来避免讨论,这将在代码中体现出。
(1)讨论版
#include
#include
using namespace std;
int main()
{
int a[105],b[105],n;
int start,end; //start标记满足要求的数列起始位置,end表示结束位置
int i,j;
while(scanf("%d",&n)!=EOF)
{
j=0;
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(i==1)
{
start=end=1;
}
else
{
if(a[i]-a[i-1]==1)
{
end++;
}
else
{
b[j]=end-start+1; //b[]数组用来存储a[]中满足要求的数列的长度
if(a[start]==1&&end!=start) b[j]++; //如果包括1,要给这段数列“加权”
if(a[end]==1000&&end!=start) b[j]++; //如果包括1000,要给这段数列“加权”
start=end=i;
j++;
}
}
}
if(n==1) printf("0\n");
else
{
b[j]=end-start+1; //循坏结束后应再做一次操作,自己思考一下,不多讲
if(a[start]==1&&end!=start) b[j]++;
if(a[end]==1000&&end!=start) b[j]++;
j++;
// for(i=0;i<=j-1;i++)
// printf("%d ",b[i]);
sort(b,b+j);
if(b[j-1]-2<0) printf("0\n");
else printf("%d\n",b[j-1]-2);
}
}
return 0;
}
(2)非讨论版
#include
#include
using namespace std;
int main()
{
int n,a[105];
int temp,ma; //ma用来记录a[]中满足要求的最长数列可以删除的元素个数,temp用来记录连续递增1的数列的长度,如果temp-2>ma,则将temp-2的值赋给ma
int i;
a[0]=0;
while(~scanf("%d",&n))
{
ma=0;temp=1;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
a[n+1]=1001; //只需令a[0]=0,a[n+1]=1001
for(i=1;i<=n+1;i++) //并多加一次循坏,即可避免讨论
{
if(a[i]-a[i-1]==1)
temp++;
else
{
ma=max(ma,temp-2);
temp=1;
}
}
ma=max(ma,temp-2); //循坏结束后也要进行多加一次处理
printf("%d\n",ma);
}
return 0;
}

被折叠的 条评论
为什么被折叠?



