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

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

 1 // File Name: buyBook.cpp
 2 // Author: Missa_Chen
 3 // Created Time: 2013年06月11日 星期二 15时03分43秒
 4 
 5 #include <iostream>
 6 #include <string>
 7 #include <algorithm>
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cmath>
11 #include <queue>
12 #include <map>
13 #include <stack>
14 #include <set>
15 #include <cstdlib>
16 
17 using namespace std;
18 
19 #define LL long long
20 const int inf = 0x3f3f3f3f;
21 const int maxn = 15;
22 int cost[maxn][maxn][maxn][maxn][maxn];
23 int bookCnt[5];
24 void sort(int& a, int &b, int& c, int& d, int& e)
25 {
26     bookCnt[0] = a; bookCnt[1] = b; bookCnt[2] = c; bookCnt[3] = d; bookCnt[4] = e;
27     sort(bookCnt, bookCnt + 5);
28     a = bookCnt[0]; b = bookCnt[1]; c = bookCnt[2]; d = bookCnt[3];e =  bookCnt[4];
29 }
30 int dfs(int a, int b, int c, int d, int e)
31 {
32     if (a + b + c + d + e == 0) return 0;
33     sort(a, b, c, d, e);
34     int& tmp = cost[a][b][c][d][e];
35     if (tmp >= 0) return tmp;
36         e -= 1;
37     tmp = 800 + dfs(a, b, c, d, e);
38     if (d >= 1)
39     {
40         d -= 1;
41         tmp = min(tmp, 2 * 8 * 95 + dfs(a, b, c, d, e));
42     }
43     else return tmp;
44     if (c >= 1)
45     {
46         c -= 1;
47         tmp = min(tmp, 3 * 8 * 90 + dfs(a, b, c, d, e));
48     }
49     else return tmp;
50     if (b >= 1)
51     {
52         b -= 1;
53         tmp = min(tmp, 4 * 8 * 80 + dfs(a, b, c, d, e));
54     }
55     else return tmp;
56     if (a >= 1)
57     {
58         a -= 1;
59         tmp = min(tmp, 5 * 8 * 75 + dfs(a, b, c, d, e));
60     }
61     return tmp;
62 }
63 int main()
64 {
65     while (scanf("%d%d%d%d%d", &bookCnt[0], &bookCnt[1], &bookCnt[2], &bookCnt[3], &bookCnt[4]))
66     {
67         memset(cost, -1, sizeof(cost));
68         printf("%lf\n",1.0 * dfs(bookCnt[0], bookCnt[1], bookCnt[2], bookCnt[3], bookCnt[4]) / 100.0);
69     }
70     return 0;
71 }

突然想起以前讨论的一个问题:记忆化搜素是不是DP。当时没什么理解。现在让我来说的化我的答案是记忆化搜素是dp(个人愚见。。)。dp的转移方程有时候很难直接从底写出。而按照从顶开始往下讨论则相对容易理解。而注意的是:此时我们虽然从顶讨论,但执行的时候仍然从底开始。从最优的子结构开始往上推。

posted @ 2013-06-11 16:39  Missa  阅读(339)  评论(0编辑  收藏  举报