Mr. Kitayuta, the Treasure Hunter
Mr. Kitayuta, the Treasure Hunter
https://ac.nowcoder.com/acm/problem/110793
题解:
也是参考了网上大佬的解法才会的
dp[i][j]表示到达第i岛屿,从上一岛屿跳过来的步长是D+j单位距离
那么将会有三种递推情况
1.这一步跳D+j的距离
2.这一步跳D+j+1的距离
3.这一步跳D+j-1的距离
分别对应图上三个if
为什么n最大只有250
因为len=30000,并且每次步长最多递增1,1+2+3+...+n=n*(n+1)/2<=30000,
n最多不超过250, 所以最长的步长不会超过D+250
但是如果每次都-1的话,数组下标就成了负数了,所以这里把起点设置为250,就消除了负数的影响。
代码:
/*Keep on going Never give up*/ #pragma GCC optimize(3,"Ofast","inline") #include<bits/stdc++.h> //#define int long long #define endl '\n' using namespace std; const int maxn = 3e4+10; const int MaxN = 0x3f3f3f3f; const int MinN = 0xc0c0c00c; typedef long long ll; const int inf=0x3f3f3f3f; const ll mod=1e9+7; int visited[maxn]; int dp[maxn][510]; int main(){ int n,d; cin>>n>>d; memset(dp,-1,sizeof dp); for(int i=1;i<=n;i++){ int x; cin>>x; visited[x]++; } int imax=visited[d]; dp[d][250]=visited[d]; for(int i=d;i<=30000;i++){ for(int j=1;j<=500;j++){ if(dp[i][j]==-1) continue; int pos=i+d+j-250; if(pos<=30000){ dp[pos][j]=max(dp[pos][j],dp[i][j]+visited[pos]); imax=max(imax,dp[pos][j]); } if(pos+1<=30000){ dp[pos+1][j+1]=max(dp[pos+1][j+1],dp[i][j]+visited[pos+1]); imax=max(imax,dp[pos+1][j+1]); } if(pos-1>i&&pos-1<=30000){ dp[pos-1][j-1]=max(dp[pos-1][j-1],dp[i][j]+visited[pos-1]); imax=max(imax,dp[pos-1][j-1]); } } } cout<<imax<<endl; return 0; }
题解 文章被收录于专栏
主要写一些题目的题解