UPC 桐桐的爬山计划

it2022-05-08  7

本题的状态量有两个,一个是攀爬次数,一个是当前位置。所以开一个二维数组,数组值为所记录的高度。状态转移则由当前高度加减攀爬高度所对应的数组值实现,也就是dp[i][j]=min(dp[i][j-a[i]](代表本次攀爬是向上的),dp[i][j]+a[i])代表本题攀爬是向下的。不过在枚举当前位置的时候可能会出现上下越界问题和位置存在性问题(就是说那几次攀爬可不可能到达某些位置),都需要一一判断。

//#include<pch.h> #include <iostream> #include <cstdio> #include <bits/stdc++.h> #include <map> #include <algorithm> #include <stack> #include <iomanip> #include <cstring> #include <cmath> #define DETERMINATION main #define lldin(a) scanf_s("%lld", &a) #define println(a) printf("%lld\n", a) #define reset(a, b) memset(a, b, sizeof(a)) const int INF = 0x3f3f3f3f; using namespace std; const double PI = acos(-1); typedef long long ll; typedef unsigned long long ull; typedef long double ld; const int mod = 1000000007; const int tool_const = 19991126; const int tool_const2 = 2000; inline ll lldcin() { ll tmp = 0, si = 1; char c; c = getchar(); while (c > '9' || c < '0') { if (c == '-') si = -1; c = getchar(); } while (c >= '0' && c <= '9') { tmp = tmp * 10 + c - '0'; c = getchar(); } return si * tmp; } ///Untersee Boot IXD2(1942) /**Although there will be many obstructs ahead, the desire for victory still fills you with determination..**/ /**Last Remote**/ int sum[500], dp[200][20000],a[500]; int DETERMINATION() { ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); ll n; cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; sum[i] = sum[i - 1] + a[i]; } dp[1][sum[1]] = sum[1];//只有一次攀爬的时候肯定是向上 for (int i = 2; i <= n; i++) { for (int current = 0; current <= sum[i]; current++)//当前位置枚举区间为0到全部向上爬的距离总和 { if ((current - a[i] < 0 || !dp[i - 1][max(0, current - a[i])]) && (current + a[i] > sum[i] || !dp[i - 1][min(sum[i], current + a[i])])) continue;//如果上下都越界或者没有相应状态可以转移过来 else if (current - a[i] < 0 ||! dp[i - 1][max(0, current - a[i])])//如果当前位置向上会越界或者没有相应状态,则向下走. dp[i][current] = max(current, dp[i - 1][min(sum[i], current + a[i])]); else if (current + a[i] > sum[i] ||!dp[i - 1][min(sum[i], current + a[i])] ) dp[i][current] = max(current, dp[i - 1][max(0, current - a[i])]); else//两个都可以 dp[i][current] = max(current, min(dp[i - 1][max(0, current - a[i])], dp[i - 1][min(sum[i], current + a[i])])); } } if (dp[n][0]) cout << dp[n][0] + 2 << endl; else cout << "IMPOSSIBLE" << endl; return 0; }

 


最新回复(0)