數列
題目描述
雖然msh長大了,但她還是很喜歡找點遊戲自娛自樂。有一天,她在紙上寫了一串數字:1,l,2,5,4。接着她擦掉了一個l,結果發現剩下l,2,4都在自己所在的位置上,即1在第1位,2在第2位,4在第4位。她希望擦掉某些數後,剩下的數列中在自己位置上的數儘量多。她發現這個遊戲很好玩,於是開始樂此不疲地玩起來……不過她不能確定最多能有多少個數在自己的位置上,所以找到你,請你幫忙計算一下!
輸入格式
第一行爲一個數n,表示數列的長度。
接下來一行爲n個用空格隔開的正整數,第i行表示數Ai。
輸出格式
一行一個整數,表示擦掉某些數後,最後剩下的數列中最多能有多少個數在自己的位置上,即Ai=i最多能有多少。
非常巧妙的一道題,刪去一個數,在這個數位置後面的數往前走一個位,可以發現最後答案一定是一個遞增的序列(這裏指Ai=i的元素),在和之間的元素只是起到了填充的作用,不用管它的值是什麼;
所以dp方程就特別好理解:
if(dp[j]&&a[i]>a[j]&&a[i]-a[j]<=i-j) dp[i]=max(dp[i],dp[j]+1);
代碼:
#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define ls k<<1
#define rs k<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int N=2010;
const int M=50100;
const LL mod=10007;
int a[1100],dp[1100];
int main(){
int n;cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
int ans=0;
for(int i=1;i<=n;i++){
if(i>=a[i]){
dp[i]=1;
for(int j=1;j<i;j++){
if(dp[j]&&a[i]>a[j]&&a[i]-a[j]<=i-j) dp[i]=max(dp[i],dp[j]+1);
}
}
ans=max(ans,dp[i]);
}
cout<<ans<<endl;
return 0;
}