您的位置:首页 > 编程语言

《编程之美》读书笔记 -- 1.4买书问题

2013-06-11 16:39 197 查看
刚看到这个题的时候就感觉是贪心或者dp,潜意识里觉得不会是那么简单的贪心。举了几个例子。推翻不了。囧。。想dp.推不出来。。看了下答案。贪心被证明是错的了。。然后就是dp。看到书上有句话突然想到 2 2 2 2 1 跟 1 2 2 2 2是一样的(应该多思考下,怎么就没发现。。)。然后就很自然的想到了记忆化搜素。然后开始敲代码。然后发现自己对于指针真的是无知了。把指针当行参来作为递归的行参。还好貌似以前有看见过这个问题。很快发现了。于是改成了以下的代码:

// File Name: buyBook.cpp
// Author: Missa_Chen
// Created Time: 2013年06月11日 星期二 15时03分43秒

#include <iostream>
#include <string>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <map>
#include <stack>
#include <set>
#include <cstdlib>

using namespace std;

#define LL long long
const int inf = 0x3f3f3f3f;
const int maxn = 15;
int cost[maxn][maxn][maxn][maxn][maxn];
int bookCnt[5];
void sort(int& a, int &b, int& c, int& d, int& e)
{
bookCnt[0] = a; bookCnt[1] = b; bookCnt[2] = c; bookCnt[3] = d; bookCnt[4] = e;
sort(bookCnt, bookCnt + 5);
a = bookCnt[0]; b = bookCnt[1]; c = bookCnt[2]; d = bookCnt[3];e =  bookCnt[4];
}
int dfs(int a, int b, int c, int d, int e)
{
if (a + b + c + d + e == 0) return 0;
sort(a, b, c, d, e);
int& tmp = cost[a][b][c][d][e];
if (tmp >= 0) return tmp;
e -= 1;
tmp = 800 + dfs(a, b, c, d, e);
if (d >= 1)
{
d -= 1;
tmp = min(tmp, 2 * 8 * 95 + dfs(a, b, c, d, e));
}
else return tmp;
if (c >= 1)
{
c -= 1;
tmp = min(tmp, 3 * 8 * 90 + dfs(a, b, c, d, e));
}
else return tmp;
if (b >= 1)
{
b -= 1;
tmp = min(tmp, 4 * 8 * 80 + dfs(a, b, c, d, e));
}
else return tmp;
if (a >= 1)
{
a -= 1;
tmp = min(tmp, 5 * 8 * 75 + dfs(a, b, c, d, e));
}
return tmp;
}
int main()
{
while (scanf("%d%d%d%d%d", &bookCnt[0], &bookCnt[1], &bookCnt[2], &bookCnt[3], &bookCnt[4]))
{
memset(cost, -1, sizeof(cost));
printf("%lf\n",1.0 * dfs(bookCnt[0], bookCnt[1], bookCnt[2], bookCnt[3], bookCnt[4]) / 100.0);
}
return 0;
}


突然想起以前讨论的一个问题:记忆化搜素是不是DP。当时没什么理解。现在让我来说的化我的答案是记忆化搜素是dp(个人愚见。。)。dp的转移方程有时候很难直接从底写出。而按照从顶开始往下讨论则相对容易理解。而注意的是:此时我们虽然从顶讨论,但执行的时候仍然从底开始。从最优的子结构开始往上推。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: