标签:sicily
Time Limit: 1 secs, Memory Limit: 256 MB
In an ill-conceived attempt to enhance the mobility of his prize cow Bessie, Farmer John has attached a pogo stick to each of Bessie‘s legs. Bessie can now hop around quickly throughout the farm, but she has not yet learned how to slow down.
To help train Bessie to hop with greater control, Farmer John sets up a practice course for her along a straight one-dimensional path across his farm. At various distinct positions on the path, he places N targets on which Bessie should try to land (1 <= N <= 1000). Target i is located at position x(i), and is worth p(i) points if Bessie lands on it. Bessie starts at the location of any target of her choosing and is allowed to move in only one direction, hopping from target to target. Each hop must cover at least as much distance as the previous hop, and must land on a target.
Bessie receives credit for every target she touches (including the initial target on which she starts). Please compute the maximum number of points she can obtain.
* Line 1: The integer N.
* Lines 2..1+N: Line i+1 contains x(i) and p(i), each an integer in the range 0..1,000,000.
* Line 1: The maximum number of points Bessie can receive.
6 5 6 1 1 10 5 7 6 4 8 8 10
25
In the sample, there are 6 targets. The first is at position x=5 and is worth 6 points, and so on. Bessie hops from position x=4 (8 points) to position x=5 (6 points) to position x=7 (6 points) to position x=10 (5 points).
2015年每周一赛第二场
先将所有奶牛按位置从左到右排好序.
考虑从左往右跳的情况,用f[i][j]表示奶牛从第i只奶牛所在的位置出发,第一步跳到
第j只奶牛所在的位置,最终能得到的最大分数.
可以得到动态规划的状态转移方程:f[i][j] = p[i] + max{f[j][k]:位置k和位置j的距
离j和位置i的距离}.
这样有O(N^2)个状态,如果状态转移的时候枚举所有大于j的k,那么复杂度是O(N^3).
但这个问题有单调性. 设g[i][j]为最优决策(也就是上面提到的最优的k值),那么有
g[i][j-1]<=g[i][j]<=g[i+1][j].
利用单调性来降低k的枚举范围,复杂度可以降到O(N^2). 从右往左跳的计算也类似. 总
复杂度O(N^2).
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; struct cow { int x, p; }c[1005]; int dp[1005][1005], n, ans = 0; bool cmp(const cow & c1, const cow & c2) { return c1.x < c2.x; } void DP(bool left2Right) { int m; memset(dp, sizeof(dp), 0); for (int i = 0; i < n; i++) dp[i][i] = c[i].p; for (int i = 0; i < n; i++) { for (int j = 0; j < i; j++) { m = 0; if (left2Right) { for (int k = j; k >= 0; k--) { if (c[j].x - c[k].x <= c[i].x - c[j].x) { if (m < dp[j][k]) { m = dp[j][k]; } } else { break; } } dp[i][j] = m + c[i].p; } else { for (int k = 0; k <= j; k++) { if (c[j].x - c[k].x >= c[i].x - c[j].x) { if (m < dp[j][k]) { m = dp[j][k]; } } else { break; } } if (m < dp[j][j]) m = dp[j][j]; dp[i][j] = m + c[i].p; } } } for (int i = 0; i < n; i++) { for (int j = 0; j <= i; j++) { if (ans < dp[i][j]) { ans = dp[i][j]; } } } } int main() { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d%d", &c[i].x, &c[i].p); sort(c, c + n, cmp); DP(true); DP(false); printf("%d\n", ans); return 0; }
标签:sicily
原文地址:http://blog.csdn.net/u012925008/article/details/44730183