动态规划题集2
来源:互联网 发布:快手视频制作软件 编辑:程序博客网 时间:2024/06/17 21:38
杭电1171
原题链接: http://acm.hdu.edu.cn/showproblem.php?pid=1171
大意是: 给定n个物品的价值,还有对应的数量。然后将这些物品分成A, B两部分,使每部分的总价值尽可能的相等,且A的价值不小于B。
开始我想的将它转成0-1背包问题。求B的最大价值,它的背包容量为总价值/2。
递推式是
这样,写出代码来,不过运行超时超空间,从网上看到要用母函数来做。
下面是用动态规划做的,样例都已通过,可是超时超空间:再下面是重新写的代码。
这个代码错误的原因是:数组范围开辟有问题,最大的价值,即背包容量应该是50*50*100,所以只能用一维数组来解决0-1背包,代码在后面。
递推式是
#include <iostream>#include <algorithm>using namespace std;int value[5005] = { 0 };int d[5005][2505] = { 0 };int main(){ int n; while (true){ int flag = 0; int sum = 0; int num = 0; cin >> n; if (n < 0) break; int v, m; for (int i = 0; i < n; i++){ cin >> v >> m; for (int j = 0; j < m; j++){ value[flag++] = v; } sum += v*m;//sum是背包容积,即总价值 num += m;//num是物品的个数 } for (int i = 0; i <= sum / 2; i++){ if (value[0] <= i) d[0][i] = value[0]; } for (int i = 1; i < num; i++){ for (int j = 1; j <= sum / 2; j++){ if (j - value[i] >= 0) d[i][j] = max(d[i - 1][j], d[i - 1][j - value[i]] + value[i]); else d[i][j] = d[i - 1][j]; } } cout << sum-d[num-1][sum/2] << " " << d[num-1][sum/2] << endl; } return 0;}
下面是更新代码,用一维数组解决0-1背包,已AC:
//#include "stdafx.h"#include <cstring> //memset的头文件,之前竟然没用过#include <iostream>#include <algorithm>using namespace std;int value[5005] = { 0 };int d[250005] = { 0 };int main(){ int n; while (true) { int flag = 0; int sum = 0; int num = 0; cin >> n; if (n < 0) break; int v, m; for (int i = 0; i < n; i++) { cin >> v >> m; for (int j = 0; j < m; j++) { value[flag++] = v; } sum += v*m;//sum是背包容积,即总价值 num += m;//num是物品的个数 } memset(d, 0, sizeof(d)); for (int i = 0; i <= sum/2; i++) { for (int j = 0; j < num; j++) { if(i-value[j]>=0) d[i] = max(d[i], d[i - value[j]] + value[j]); } } cout << sum - d[sum/2] << " " << d[sum / 2] << endl; } return 0;}
杭电1176 免费馅饼
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1176
大意是:有0-10这11个点,馅饼在不同的时间落在这些点上。但是有个人初始位置在5,每秒只能移动一个单位, 求它最多能拿到多少馅饼。
这题是和数字三角形差不多的题,就是要从最后开始记录,每次记录都是和下一次的时间点的位置有关。
设a[i][j]表示第j秒有馅饼落在i位置
d[i][j]表示第i个位置时,第j秒取得的最大馅饼数量。
d[i][j] = max( d[i - 1][j + 1], d[i][j + 1] , d[i+1][j+1] )+ a[i][j] ;
递推式为上式,注意处理边界条件即可。代码如下:
#include <iostream>#include <algorithm>#include <cstdlib>#include <cstring>#include "stdio.h"using namespace std;int a[11][100005] = { 0 };//a[i][j]表示第j秒有一个馅饼落在第i个地方int d[11][100005]; //其实如果空间不足,用一个数组也行int main(){ int n; while (true){ memset(a, 0, sizeof(a)); scanf("%d", &n); if (n == 0) break; int x, t, maxt = 0; for (int i = 0; i < n; i++){ scanf("%d%d", &x, &t); a[x][t]++; maxt = max(maxt, t);//找出最大的t来,便于遍历数组 } for (int i = 0; i<11; i++) d[i][maxt] = a[i][maxt]; for (int j = maxt - 1; j >= 0; j--){ d[10][j] = max(d[9][j + 1], d[10][j + 1]) + a[10][j]; d[0][j] = max(d[1][j + 1], d[0][j + 1]) + a[0][j]; for (int i = 1; i < 10; i++){ d[i][j] = max(d[i - 1][j + 1], d[i][j + 1]); d[i][j] = max(d[i][j],d[i+1][j+1]) + a[i][j]; } } printf("%d\n", d[5][0]); } return 0;}
阅读全文
0 0
- 动态规划题集2
- 动态规划 HDU 动态规划题集
- 动态规划题集
- 动态规划题集
- 【Algorithm】动态规划 (1) HDU 动态规划题集
- 动态规划 HDU 动态规划题集1\
- 动态规划 (1) HDU 动态规划题集
- pku动态规划题集
- ACM 动态规划题集
- hdoj动态规划题集
- poj 动态规划题集
- hdu 动态规划题集
- PKU动态规划题集
- 动态规划题集1
- POJ 动态规划题集
- hdu 动态规划题集
- 《转载》hdu 动态规划题集
- 【转】经典动态规划题集
- JavaScript 的 API 设计原 则
- 抽象工厂模式
- [算法机试模拟题]1007.小黄车
- 简历编写及面试技巧解析
- CodeForces 214B
- 动态规划题集2
- 理解strcat、strncat、strcpy、strncy、strcmp、strncmp。
- es6-变量解构赋值
- VB-TabIndex、GotFocus、SetFocus
- Linux学习笔记 --Bash ScriptsII
- 网站10000IP要多少带宽才合适
- Codeforces Gym 101234H Split Game
- MySQL日常练习;
- 进制的基础与进阶