挑战程序设计竞赛笔记_P55
2017-08-16 19:19
309 查看
//理解的时候一定要看打出来的表理解!!! #include #include #define max(a, b) a > b ? a : b const int MAX_N = 100; const int MAX_W = 10000; int n, W, w[MAX_W], v[MAX_N], dp[MAX_N + 1][MAX_W + 1]; int rec1(int i, int j) { memset(dp, -1, sizeof(dp)); if (dp[i][j] >= 0) return dp[i][j]; if (i == n) return 0; if (j < w[i]) return dp[i][j] = rec1(i + 1, j); else return dp[i][j] = max(rec1(i + 1, j), rec1(i + 1, j - w[i]) + v[i]); } int rec2(int i, int j) { memset(dp, -1, sizeof(dp)); if (dp[i][j] >= 0) return dp[i][j]; if (i == 0) return 0; if (j < w[i - 1]) return dp[i][j] = rec2(i - 1, j); else return dp[i][j] = max(rec2(i - 1, j), rec2(i - 1, j - w[i - 1]) + v[i - 1]); } int arr1() { memset(dp, 0, sizeof(dp)); for (int i = n - 1; i >= 0; i--) { for (int j = 1; j <= W; j++) { if (j < w[i]) dp[i][j] = dp[i + 1][j]; else dp[i][j] = max(dp[i + 1][j], dp[i + 1][j - w[i]] + v[i]); } } return dp[0][W]; } int arr2() { memset(dp, 0, sizeof(dp)); for (int i = 1; i <= n; i++) { for (int j = 1; j <= W; j++) { if (j < w[i - 1]) dp[i][j] = dp[i - 1][j]; else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i - 1]] + v[i - 1]); } } return dp [W]; } int arr3() { //数组方法3,同2 memset(dp, 0, sizeof(dp)); for (int i = 0; i < n; i++) { for (int j = 1; j <= W; j++) { if (j < w[i]) dp[i + 1][j] = dp[i][j]; else dp[i + 1][j] = max(dp[i][j], dp[i][j - w[i]] + v[i]); } } return dp [W]; } int arr4(){ memset(dp, 0, sizeof(dp)); for (int i = 0; i < n; i++){ //这里从j=1开始不行!!因为dp[i+1][j+w[i]]中j=0是有用的!而之所以前面的那些个数组方法可以,是因为他们根本用不着j=0来推断右下的元素 for (int j = 0; j <= W; j++){ if (w[i] + j <= W){ dp[i + 1][j + w[i]] = dp[i][j] + v[i]; } dp[i + 1][j] = max(dp[i][j], dp[i + 1][j]); // if (w[i] + j <= W){ // dp[i + 1][j + w[i]] = max(dp[i + 1][j + w[j]], dp[i][j] + v[i]); // }//这个改动是不是666? } } return dp [W]; } void print() { printf(" i\\j"); for (int i = 0; i <= W; i++) printf("%4d", i); putchar(10); for (int i = 0; i <= n; i++) { printf("%4d", i); for (int j = 0; j <= W; j++) printf("%4d", dp[i][j]); putchar(10); } putchar(10); } int main() { freopen("E:/My/input.txt", "r", stdin); scanf("%d%d", &n, &W); for (int i = 0; i < n; i++) scanf("%d%d", w + i, v + i); printf("arr1:%d\n", arr1()); print(); printf("arr2:%d\n", arr2()); print(); printf("arr3:%d\n", arr3()); print(); printf("arr4:%d\n", arr4()); print(); // printf("rec1:%d\n", rec1(0, W)); // print(); // printf("rec2:%d\n", rec2(n, W)); // print(); return 0; }
相关文章推荐
- 挑战程序设计竞赛(第2版) 第2章笔记
- 挑战程序设计竞赛笔记_计数DP_P68
- 挑战程序设计竞赛2 数据结构与算法学习笔记
- 挑战程序设计竞赛 数据结构与竞赛笔记插入排序
- ACM Yogurt factory(挑战程序设计竞赛)
- [挑战程序设计竞赛] POJ 3050 - Hopscotch
- ACM Packets(挑战程序设计竞赛)
- 每日一题 No.40 挑战程序设计竞赛
- dp-挑战程序设计竞赛-状态的选择 多重部分和 LIS
- 挑战程序设计竞赛——1.61三角形
- 挑战编程 程序设计竞赛训练手册-1.6.2 扫雷(Minesweeper)
- 挑战程序设计竞赛(第2版) 第2章习题
- 挑战程序设计竞赛 2.1迷宫的最短路径
- poj2431 Expedition (优先队列) 挑战程序设计竞赛
- 挑战程序设计竞赛-初出茅庐(最基础的“穷竭搜索”)
- poj2385 基础的动态规划算法 <挑战程序设计竞赛>
- ACM Cleaning Shifts(挑战程序设计竞赛)
- 挑战程序设计竞赛 3.2 常用技巧精选(一)
- 系统性训练,励志刷完挑战程序设计竞赛-代码整理43~68【初级篇】
- 挑战程序设计竞赛 1.6.1 三角形 计算组合三角形的最大周长