
2.3 记录结果再利用的“动态规划” 基础的动态规划算法
2棵苹果树在T分钟内随机由某一棵苹果树掉下一个苹果,奶牛站在树#1下等着吃苹果,它最多愿意移动W次,问它最多能吃到几个苹果。
定义dp[x][y][z]表示第x + 1分的时候经过y次移动站在了z+1树下能吃到的最大苹果数,然后搜索所有的xyz组合,更新dp。
#include <iostream>
#include <algorithm>
using namespace std;
int tree[1000];
int dp[1000][32][2]; // dp[x][y][z]表示第x + 1分的时候经过y次移动站在了z+1树下能吃到的最大苹果数
inline int move(const int &k)
{
return k == 0 ? 1 : 0;
}
///////////////////////////SubMain//////////////////////////////////
int main(int argc, char *argv[])
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int T, W;
cin >> T >> W;
for (int i = 0; i < T; ++i)
{
int t;
cin >> t;
tree[i] = t - 1;
}
if (tree[0] == 0)
{
dp[0][0][0] = 1;
}
else
{
dp[0][1][1] = 1;
}
for (int i = 0; i < T - 1; ++i)
{
for (int j = 0; j <= W; ++j)
{
for (int k = 0; k < 2; ++k)
{
if (k == tree[i + 1])
{
// 下一个苹果掉在当前树下,那么下一分钟?
// 站着不动吃一个
dp[i + 1][j][k] = max(dp[i + 1][j][k], dp[i][j][k] + 1);
// 移动没吃到,不变
dp[i + 1][j + 1][move(k)] = max(dp[i + 1][j + 1][move(k)], dp[i][j][k]);
}
else
{
// 下一个苹果掉在另一树下,那么下一分钟?
// 站着不动没吃到
dp[i + 1][j][k] = max(dp[i + 1][j][k], dp[i][j][k]);
// 移动吃一个
dp[i + 1][j + 1][move(k)] = max(dp[i + 1][j + 1][move(k)], dp[i][j][k] + 1);
}
}
}
}
cout << *max_element(dp[T - 1][0], dp[T - 1][0] + (W + 1) * 2) << endl;
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
system("out.txt");
#endif
return 0;
}
///////////////////////////End Sub//////////////////////////////////
知识共享署名-非商业性使用-相同方式共享:码农场 » POJ 2385 Apple Catching 题解 《挑战程序设计竞赛(第2版)》
码农场