HDU-P1176:免费馅饼[动态规划]
HDU-P1176:免费馅饼[动态规划]
题目
思路
由于是中文的题面,题目的大意还是很好理解的,就是给出一个类似于数塔的二维数组,求从数塔顶到数塔低经过路径上数字的最大的和,这样的问题可以用搜索或者动态规划来解决。本人一开始使用的广度优先搜索,由于没有看清题目中的"多组测试用例",WA了好几发,改过来之后也是内存超限…
万般无奈之下,只能操练起了万恶的动态规划,动态规划在这道题中的主要难点是由于起点是确定的,不能自底向上来进行状态转移,所以我们要从顶向下进行转移,转移方程并不难。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int dp[11][100005];
int main(void)
{
int x, T, n, maxt;
while(~scanf("%d", &n) && n) {
memset(dp, 0, sizeof(dp));
maxt = 0;
for(int i = 0; i < n; ++i) {
scanf("%d%d", &x, &T);
dp[x][T]++;
maxt = max(maxt, T); //maxn存放当前测试组的最高的时间点
}
for(int i = maxt-1; i >= 0; --i) {
dp[0][i] += max(dp[0][i+1], dp[1][i+1]); //注意对边界数据的处理
for(int j = 9; j > 0; --j)
dp[j][i] = max(dp[j][i+1], max(dp[j-1][i+1], dp[j+1][i+1]))+dp[j][i];
dp[10][i] += max(dp[10][i+1], dp[9][i+1]); //同上
}
printf("%d\n", dp[5][0]);
}
return 0;
}
顺便贴一下广搜的代码,看看有没有人能剪剪枝。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
int dir[3] = {-1, 0, 1};
int n[11][100005];
int N;
int MAXT, maxsum;
struct node {
int x, y, num;
node(int X = 5, int Y = 1, int N = 0) : x(X), y(Y), num(N) {}
};
queue<node> que;
void BFS() {
maxsum = 0;
que.push(node(5, 0, 0));
while(que.size() != 0) {
node tmp = que.front();
int num = tmp.num;
que.pop();
for(int i = 0; i < 3; ++i) {
int x = tmp.x+dir[i];
int y = tmp.y+1;
if(x < 0 || x > 10) continue;
if(y > MAXT) continue;
if(maxsum == N) break;
que.push(node(x, y, num+n[x][y]));
maxsum = maxsum>num+n[x][y] ? maxsum : num+n[x][y];
}
}
printf("%d\n", maxsum);
}
int main(void)
{
int x, T;
memset(n, 0, sizeof(n));
MAXT = 0;
while(~scanf("%d", &N) && N) {
for(int i = 0; i < N; ++i) {
scanf("%d", &x);
scanf("%d", &T);
n[x][T]++;
MAXT = MAXT>T?MAXT:T;
}
BFS();
}
return 0;
}
题外话
这半夜里做题效率就是低,还因为这鸽了舍友好几天的晨跑了,得调整调整作息了。还有这博文咋越写越多,访客量还越来越少了…
浙公网安备 33010602011771号