EcustOJ P109跳一跳(离散化+dp)

时间:2023-12-28 12:34:26

题目链接

感觉这道题我看了很多天,胡思乱想啊,一开始觉得记忆化搜索会可能T啊,,可能出题人的数据卡的好就稳T了的感觉。。后来想了想,好像离散化一下,记一下位置之后再记忆化搜索就应该稳了吧。。(好像直接搜也不会T的,,??)

#include <set>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <bitset>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#define MAXN 1010100
#define LL long long
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ll __int64
#define INF 0x7fffffff
#define cs(s) freopen(s,"r",stdin)
#define mem(x) memset(x,0,sizeof(x))
#define PI acos(-1)
#define eps 1e-10
using namespace std;
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int lcm(int a,int b){return a/gcd(a,b)*b;}
LL powmod(LL a,LL b,LL MOD){LL ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
//head
const int maxn=1e5+1;
int dp[maxn][3],ans;
int a[maxn],b[maxn],pos[maxn],n;
int dfs(int now,int sta){
if(now==n)return dp[now][sta]=1;
if(dp[now][sta]!=-1)return dp[now][sta];
if(sta==0){
int cnt=0;
while(pos[a[now]+cnt]<=now&&a[now]+cnt+1<=n)cnt++;
if(pos[a[now]+cnt]<=now)return dp[now][sta]=0;
return dp[now][sta]=dfs(pos[a[now]+cnt],1);
}else {
int cnt=0;
while(pos[a[now]-cnt]<=now&&a[now]-cnt-1>=1)cnt++;
if(pos[a[now]-cnt]<=now)return dp[now][sta]=0;
return dp[now][sta]=dfs(pos[a[now]-cnt],0);
}
}
int main(){
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i],b[i]=a[i];
sort(b+1,b+1+n);
int cnt=unique(b+1,b+1+n)-b-1;
for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+1+cnt,a[i])-b,pos[a[i]]=i;
memset(dp,-1,sizeof(dp));
for(int i=1;i<=n;i++)if(dfs(i,0))ans++;
cout<<ans<<endl;
return 0;
}

第二天 ,写了一个非递归的版本。。。快一点,大致都差不多的。

dp[i][0]=dp[pos][1],(a[i]<a[pos],且a[pos]>a[p] {p!=pos且p>i且a[p]<a[i]}。

dp[i][1]=dp[pos][0],(a[i]>a[pos],且a[pos]<a[p] {p!=pos且p>i且a[p]>a[i]}。

#include <set>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <bitset>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#define MAXN 1010100
#define LL long long
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ll __int64
#define INF 0x7fffffff
#define cs(s) freopen(s,"r",stdin)
#define mem(x) memset(x,0,sizeof(x))
#define PI acos(-1)
#define eps 1e-10
using namespace std;
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int lcm(int a,int b){return a/gcd(a,b)*b;}
LL powmod(LL a,LL b,LL MOD){LL ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
//head
const int maxn=1e5+1;
int dp[maxn][3],ans;
int a[maxn],b[maxn],pos[maxn],n;
int main(){
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i],b[i]=a[i];
sort(b+1,b+1+n);
int cnt=unique(b+1,b+1+n)-b-1;
for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+1+cnt,a[i])-b,pos[a[i]]=i;
dp[n][0]=dp[n][1]=1;
for(int i=n-1;i>=1;i--){
int cnt=0;
while(pos[a[i]+cnt]<=i&&a[i]+cnt+1<=n)cnt++;
if(pos[a[i]+cnt]<=i)dp[i][1]=0;
else dp[i][1]=dp[pos[a[i]+cnt]][0];
cnt=0;
while(pos[a[i]-cnt]<=i&&a[i]-cnt-1>=1)cnt++;
if(pos[a[i]-cnt]<=i)dp[i][0]=0;
else dp[i][0]=dp[pos[a[i]-cnt]][1];
}
for(int i=1;i<=n;i++)if(dp[i][1]||i==n)ans++;
cout<<ans<<endl;
return 0;
}