刚看到这个题的时候就感觉是贪心或者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的转移方程有时候很难直接从底写出。而按照从顶开始往下讨论则相对容易理解。而注意的是:此时我们虽然从顶讨论,但执行的时候仍然从底开始。从最优的子结构开始往上推。