POJ 1042 Gone Fishing (DP)
来源:互联网 发布:制作ubuntu u盘启动盘 编辑:程序博客网 时间:2024/06/05 07:49
解题思路 (DP)
假如在给定时间h内,最远到达第个i湖时,最多捕鱼数为F(i, h), 那么问题的解为
MAX{F(i, h)}, i=1...n考虑最远到达第i个湖时,除去路途中的时间,最多的有效捕鱼时间为 hi = h - sum(t[0]+...+t[i-1]), 那么:
F(i, h) <=> maxfish(i, hi)
且有
MAX{F(i, h)} = MAX{maxfish(i, hi)} = MAX{maxfish(1,h1), ..., maxfish(n,hn)}
这里maxfish(i, k)表述为原问题的简化形式:
不考虑湖之间的消耗时间(即t0=t1=...=t[i-1]=0),给定时间k内,在i个湖的最多捕鱼数。
建立递推关系,maxfish(i, k)取下列最大者:
{ k时间内在i-1个湖的最多捕鱼数; k时间内在第i个湖捕鱼时间大于0的所有情况的最多捕鱼数 }
即
maxfish(i, k) = MAX{ maxfish(i-1,k), lakefish(i,j)+maxfish(i-1,k-j) }, 1<j<=k
lakefish(i,j)表示在第i个湖捕鱼j时间能捕到的总鱼数。
原问题MAX{maxfish(i, hi)},只需构造maxfish(n,hn)的解,maxfish(1,h1),...,maxfish(n-1,h[n-1])为过程中更小规模的子问题的解,这n个不同规模的子问题的解的最大者,即为原问题的解。
这个思路的关键在于,将问题简化为不考虑湖之间花费的时间,能更容易使用动态规划来求解。
注意点:
1. 计算过程中h时间转化为单位时间h=h*12, 求解完后输出时间均*5
2. 剩余时间放到第一个湖
代码
#include <iostream>#include <memory.h>using namespace std;int f[26];int d[26];int t[25];int lakefish[26][193];int maxfish[26][193]; int spent[26][193]; int spentMax[26];int main(int argc, char** argv){ int cases = 0; int n, h; while (cin >> n) { if (n > 0 && cases > 0) { cout << endl; } if (n == 0) { break; } ++ cases; // input cin >> h; h = h * 12; for (int i = 1; i <= n; ++i) { cin >> f[i]; } for (int i = 1; i <= n; ++i) { cin >> d[i]; } for (int i = 1; i < n; ++i) { cin >> t[i]; } // lakefish(i,j) memset(lakefish, 0, sizeof(lakefish)); int fk = 0; for (int i = 1; i <= n; ++i) { for (int k = 1; k <= h; ++k) { fk = f[i] - d[i] * (k - 1); if (fk > 0) { lakefish[i][k] = lakefish[i][k-1] + fk; } else { lakefish[i][k] = lakefish[i][k-1]; } } } // 1. maxfish(i, k) = MAX{ maxfish(i-1,k), lakefish(i,j)+maxfish(i-1,k-j)}, 1<j<=k // 2. result = MAX{maxfish(1,h1), ..., maxfish(n,hn)} memset(maxfish, 0, sizeof(maxfish)); memset(spent, 0, sizeof(spent)); memset(spentMax, 0, sizeof(spentMax)); int hi = h; int fishij = -1; int maxfishnk = -1, maxfishn = -1, maxfishh = -1; for (int i = 1; i <= n; ++i) { hi = hi - t[i-1]; for (int k = 1; k <= hi; ++k) { maxfish[i][k] = maxfish[i-1][k]; spent[i][k] = 0; for (int j = 1; j <= k; ++j) { fishij = lakefish[i][j] + maxfish[i-1][k-j]; if (fishij > maxfish[i][k]) { maxfish[i][k] = fishij; spent[i][k] = j; } } if (k == hi && maxfish[i][k] > maxfishnk) { maxfishnk = maxfish[i][k]; maxfishn = i; maxfishh = k; } } } // output int i = maxfishn; int k = maxfishh; while (i > 0) { spentMax[i] = spent[i][k]; k = k - spentMax[i]; if (i == 1) { spentMax[i] += k; } -- i; } for (int i = 1; i <= n; ++i) { if (i > 1) { cout << ", "; } cout << spentMax[i]*5; } cout << endl << "Number of fish expected: " << maxfishnk <<endl; } return 0;}
0 0
- poj 1042 Gone Fishing(DP)
- POJ 1042 Gone Fishing( DP )
- POJ 1042 Gone Fishing (DP)
- poj 1042 Gone Fishing(DP)
- POJ 1042 Gone Fishing (DP) 2
- POJ 1042 Gone Fishing
- poj 1042 Gone Fishing
- POJ 1042 Gone Fishing
- poj 1042 gone fishing
- POJ-1042:Gone Fishing
- poj 1042 Gone Fishing
- poj 1042 Gone Fishing
- POJ 1042 Gone Fishing
- [poj] 1042 Gone Fishing
- poj 1042Gone Fishing
- Poj 1042 Gone Fishing
- POJ 1042 Gone Fishing
- POJ 1042 Gone Fishing
- hdu5323&15年多校集训(3)h题
- [BZOJ1801][Ahoi2009]chess 中国象棋
- 医疗时鲜资讯:互联网+医疗,技术 OR 需求
- 机试算法讲解: 第21题 再谈进制转换
- 浅谈大脑思维和对未来计算机的设想(3)
- POJ 1042 Gone Fishing (DP)
- 机试算法讲解: 第22题 是你的最大公约数
- 嵌入式操作系统ucos与linux比较
- SQL注入与编码技术
- NYOJ214单调递增子序列(二)【dp+二分查找】
- objective C程序 无参方法和有参方法声明实现及调用
- 机试算法讲解: 第23题 哦,最小公倍数
- 【HDU2069】【Coin Change】
- 黑马程序员——collection的Set集合