题解 P1567 【统计天数】
题目的本质很好理解:求一个序列的最长上升子串
(附:子串指必须是连续的)
给出代码:
#include<bits/stdc++.h>
using namespace std;
int n,a[10000005],dp[10000005]={0,1};
int main()
{
cin>>n;
int ans=1;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=2;i<=n;i++)
{
if(a[i]>a[i-1])dp[i]=dp[i-1]+1;
else dp[i]=1;
if(dp[i]>ans)ans=dp[i];
}
cout<<ans;
}
附:100分记录
最后给出一份经过一系列难以理解的神奇优化的代码(97ms):
#include<stdio.h>
inline int read()
{
register char ch=getchar();
register int x=0;
while(ch>'9'||ch<'0')ch=getchar();
while(ch<='9'&&ch>='0')x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return x;
}
inline void print(int x)
{
// if(!x){putchar('0');return;} 这一行没有用,因为答案肯定不是0
register int cnt=0;
char ch[12];
while(x)ch[cnt++]=x%10+48,x/=10;
while(cnt--)putchar(ch[cnt]);
}
int main()
{
register int n=read(),ans=0,x=0,y,mans=0;
while(n--)ans=((y=read())>x)?ans+1:1,(ans>mans)&&(mans=ans),x=y;
print(mans);
}
提交记录
Update:2019/8/8,因为码风变化较大,又学到了更多常数优化相关的东西,而且洛谷提交记录界面改变,所以重打了一遍代码,并更新文中链接。同时对其他部分的排版做翻新。
Update:2020/4/7,又用了一些奇怪的优化,代码如下:
#include<stdio.h>
const unsigned TOP=1200000;//反复测试出的数据
char T[TOP],*x1(T),*y1(T);
inline char get()
{
x1==y1&&(y1=(x1=T)+fread(T,1,TOP,stdin));return *x1++;
}
inline unsigned r()
{
register unsigned x;register char c;
(c=get())&16?x=c&15:x=get()&15;//钻了输入格式的空子
while((c=get())&16)x=x*10+(c&15);
return x;
}
int main()
{
register unsigned n(r()),a(0),x(0),y,m(0);char ch[6];//注意这个是可以Hack的,当且仅当答案为1e6时会RE。想一想怎么解决
while(n--)(y=r())>x?++a:((a>m)&&(m=a),a=1),x=y;
(a>m)&&(m=a);
register char* c(ch+5);
while(m)*--c=m%10|48,m/=10;
fputs(c,stdout);
}
请结合此图进行理解: