【题目描述】
小M很喜欢找点游戏自娱自乐。有一天,她在纸上写了一串数字:1,1,2,5,4。接着她擦掉了一个1,结果发现剩下1,2,4都在自己所在的位置上,即1在第1位,2在第2位,4在第4位。她希望擦掉某些数后,剩下的数列中在自己位置上的数尽量多。她发现这个游戏很好玩,于是开始乐此不疲地玩起来……不过她不能确定最多能有多少个数在自己的位置上,所以找到你,请你帮忙计算一下!
【输入格式】
第一行为一个数n,表示数列的长度。
接下来一行为n个用空格隔开的正整数,第i行表示数Ai。
【输出格式】
一行一个整数,表示擦掉某些数后,最后剩下的数列中最多能有多少个数在自己的位置上,即Ai=i最多能有多少。
【样例输入】
5
1 1 2 5 4
【样例输出】
3
【提示】
对于20%的数据,n≤20;
对于60%的数据,n≤100;
对于100%的数据,n≤l000

1 #include<iostream> 2 #include<cstdio> 3 4 5 using namespace std; 6 7 8 int main() 9 { 10 freopen("seqgame.in","r",stdin); 11 freopen("seqgame.out","w",stdout); 12 int ac[1010]={0}; 13 int dp[1010]={0}; 14 int n;int max; 15 cin>>n; 16 int i,j; 17 for(i=1;i<=n;i++) 18 cin>>ac[i]; 19 for(i=1;i<=n;i++) 20 { 21 if(ac[i]>i) 22 { 23 dp[i]=0; 24 continue; 25 } 26 max=0; 27 for(j=0;j<i;j++) 28 if(ac[i]>ac[j]) 29 if((ac[i]-ac[j])<=(i-j)) 30 { 31 if(dp[j]>max)max=dp[j]; 32 } 33 dp[i]=max+1; 34 } 35 max=0; 36 for(i=1;i<=n;i++) 37 if(dp[i]>max)max=dp[i]; 38 cout<<max<<endl; 39 return 0; 40 }
代码分析:
其实该题就是求最长递增子序列;只不过是加了一些附加的条件;
首先,应该是该元素的值应该大于等于该元素的下标;否则不行,即赋值为0;
其次,元素之差要小于等于下标之差;
在上边这些条件下找出DP数组中第i个元素前的最大值加1赋给dp[i];
最后在dp数组中寻找最大值然后输出;