Mr. Kitayuta, the Treasure Hunter
思路
一眼看过去感没跑了,但是这个的数组着实开不下,但是我们不难发现有用的状态并不是太多,所以想想有没有什么方法来进行一下空间的优化,最多500个上下移动的步数我就不证明了。
我们定义,表示我们从某个位置走了步到这里,所以我们有状态转移方程。
代码
/* Author : lifehappy */ #pragma GCC optimize(2) #pragma GCC optimize(3) #include <bits/stdc++.h> #define mp make_pair #define pb push_back #define endl '\n' #define mid (l + r >> 1) #define lson rt << 1, l, mid #define rson rt << 1 | 1, mid + 1, r #define ls rt << 1 #define rs rt << 1 | 1 using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii; const double pi = acos(-1.0); const double eps = 1e-7; const int inf = 0x3f3f3f3f; inline ll read() { ll f = 1, x = 0; char c = getchar(); while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); } return f * x; } const int N = 3e4 + 10; int num[N], n, d; int dp[N][510]; int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); n = read(), d = read(); for(int i = 1; i <= n; i++) { num[read()]++; } memset(dp, -1, sizeof dp); dp[d][250] = num[d]; int ans = num[d]; for(int i = 1; i <= 30000; i++) { for(int j = 1; j <= 500; j++) { int last = i - j - d + 250; if(last < 0 || last >= i) continue;//必不可能从小于0的地方走,也不能倒着走。 for(int k = -1; k <= 1; k++) { if(j + k > 0 && dp[last][j + k] != -1) { dp[i][j] = max(dp[i][j], dp[last][j + k] + num[i]); } } ans = max(ans, dp[i][j]); } } cout << ans << endl; return 0; }