标签:答案 algo print amp idt 代码 for src std
T1 遭遇
【题意】
??座楼房,立于城中。 第??座楼,高度???。 你需要一开始选择一座楼,开始跳楼。在第??座楼准备跳楼需要????的花费。 每次可以跳到任何一个还没有跳过的楼上去。但跳楼是有代价的,每次跳到另 外一座楼的代价是两座楼高度的差的绝对值,最后一次从楼上跳到地面上不需 要代价(只能跳到地上一次)。为在代价不超过??的情况下,最多跳几次楼。 (一座楼只能跳一次,且每次跳楼都要计算准备的花费)
【题解】
跳楼时,楼房的高度是具有单调性的,所以先按照高度排序。
f[i][j]表示已经跳了j次楼,到了第i座楼时的最小花费。
f[ i ][ j ] 可以从1到 i - 1 中任何一栋楼转移得到。
代码:
#include <cstdio> #include <cstring> #include <algorithm> const int MAXN = 57; int n, T, f[MAXN][MAXN], ans; struct Node { int hi, wt; bool operator < (Node dd) { return hi < dd.hi; } } node[MAXN]; int main() { freopen("meet.in", "r", stdin); freopen("meet.out", "w", stdout); scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &node[i].wt); for (int i = 0; i < n; i++) scanf("%d", &node[i].hi); scanf("%d", &T); std::sort(node, node + n); memset(f, 0x7f, sizeof(f)); // 并不知道为什么,初始化的值大一些的话,会使一些点的答案变为 50. for (int i = 0; i < n; i++) { f[i][1] = node[i].wt; if (f[i][1] <= T) ans = std::max(ans, 1); } for (int i = 0; i < n; i++) for (int j = 2; j <= i + 1; j++) for (int k = 0; k <= i - 1; k++) { f[i][j] = std::min(f[i][j], f[k][j - 1] + node[i].hi - node[k].hi + node[i].wt); if (f[i][j] <= T) ans = std::max(ans, j); } printf("%d\n", ans); return 0; }
【2017.11.07】noip赛前集训 | T1 遭遇【DP】
标签:答案 algo print amp idt 代码 for src std
原文地址:http://www.cnblogs.com/ExileValley/p/7798730.html