算法导论——16.1-5动态规划解决活动选择带值问题
2017-03-28 20:54
211 查看
原活动问题是用贪心算法解得,实质是就是不重合区间择多问题。
新的问题变形后,每个区间的都带上的值,求如何选择才能得到不重合区间且值最大。
想了想只能用dp来解决,下面附我的解题思路+代码
1.用act[max][3]记录所有活动的状态(开始时间|结束时间|价值)
act[n-1][0]表示第n个活动的开始时间,act[n-1][1]]表示第n个活动的结束时间,act[n-1][2],表示第n个活动的价值
2.用maxVal[max][2]记录所有活动的最大价值(最大价值和|结束时间)
3.预处理,将act活动按照结束时间来排序,从小到大
4.for(maxVal[i] 表示当前活动 从 0 ~ count)
maxVal[i][0] = act[i][2];//将活动最大值和设为当前活动价值
maxVal[i][1] = act[i][1];//将活动结束点设为当前活动结束点
for(act[j] 表示之前活动 从 当前活动-1 ~ 0)
//当前活动开始时间 >= 之前活动结束时间 && 当前活动最大值和< 之前活动最大值和+当前活动最大值
//当前活动可以接上之前活动 并且 当前活动接上之前活动后的最大值和大于当前活动之前的最大值和
if (atv[i][0] >= maxVal[j][1] && maxVal[i][0] < maxVal[j][0] + atv[j][2])
maxVal[i][0] = maxVal[j][0] + atv[j][2];//当前活动最大值和更新为之前活动最大值和+当前活动最大值
maxVal[i][1] = atv[i][1];//更新最大价值结束点为当前活动结束点
break;
//不能接上前面活动&&当前活动最大价值<前面活动最大价值
else if (atv[i][0] < maxVal[j][1] && maxVal[i][0] < maxVal[j][0])
maxVal[i][0] = maxVal[j][0]; //更新当前活动最大价值为前面活动的最大价值,
maxVal[i][1] = maxVal[j][1];//更新当前活动最大值结束时间为前面活动最大值结束时间
只是考虑两种情况会更新maxVal
由于每次遍历都可以得到最大价值点,所以就不用遍历所有先前节点,这样可以保证算法复杂度在O(nlog2n)
下面是c++源代码,如果有不对的地方,欢迎指正
新的问题变形后,每个区间的都带上的值,求如何选择才能得到不重合区间且值最大。
想了想只能用dp来解决,下面附我的解题思路+代码
1.用act[max][3]记录所有活动的状态(开始时间|结束时间|价值)
act[n-1][0]表示第n个活动的开始时间,act[n-1][1]]表示第n个活动的结束时间,act[n-1][2],表示第n个活动的价值
2.用maxVal[max][2]记录所有活动的最大价值(最大价值和|结束时间)
3.预处理,将act活动按照结束时间来排序,从小到大
4.for(maxVal[i] 表示当前活动 从 0 ~ count)
maxVal[i][0] = act[i][2];//将活动最大值和设为当前活动价值
maxVal[i][1] = act[i][1];//将活动结束点设为当前活动结束点
for(act[j] 表示之前活动 从 当前活动-1 ~ 0)
//当前活动开始时间 >= 之前活动结束时间 && 当前活动最大值和< 之前活动最大值和+当前活动最大值
//当前活动可以接上之前活动 并且 当前活动接上之前活动后的最大值和大于当前活动之前的最大值和
if (atv[i][0] >= maxVal[j][1] && maxVal[i][0] < maxVal[j][0] + atv[j][2])
maxVal[i][0] = maxVal[j][0] + atv[j][2];//当前活动最大值和更新为之前活动最大值和+当前活动最大值
maxVal[i][1] = atv[i][1];//更新最大价值结束点为当前活动结束点
break;
//不能接上前面活动&&当前活动最大价值<前面活动最大价值
else if (atv[i][0] < maxVal[j][1] && maxVal[i][0] < maxVal[j][0])
maxVal[i][0] = maxVal[j][0]; //更新当前活动最大价值为前面活动的最大价值,
maxVal[i][1] = maxVal[j][1];//更新当前活动最大值结束时间为前面活动最大值结束时间
只是考虑两种情况会更新maxVal
由于每次遍历都可以得到最大价值点,所以就不用遍历所有先前节点,这样可以保证算法复杂度在O(nlog2n)
下面是c++源代码,如果有不对的地方,欢迎指正
#include <stdio.h> using namespace std; #pragma warning(disable:4996) //预处理,按结束时间排序 void preDeal(int arr[][3], int len){ for (int i = len - 1; i > 0; i--){ for (int j = 0; j < i; j++){ if (arr[j][1]>arr[j + 1][1]){ arr[j][0] += arr[j + 1][0]; arr[j][1] += arr[j + 1][1]; arr[j][2] += arr[j + 1][2]; arr[j + 1][0] = arr[j][0] - arr[j + 1][0]; arr[j + 1][1] = arr[j][1] - arr[j + 1][1]; arr[j + 1][2] = arr[j][2] - arr[j + 1][2]; arr[j][0] -= arr[j + 1][0]; arr[j][1] -= arr[j + 1][1]; arr[j][2] -= arr[j + 1][2]; } } } } int main(){ int cnt; int atv[1000][3], maxVal[1000][2];//start,finish,value|val,finish while (scanf("%d", &cnt)){ for (int i = 0; i < cnt; i++){ scanf("%d%d%d", &atv[i][0], &atv[i][1], &atv[i][2]); } preDeal(atv, cnt); for (int i = 0; i < cnt; i++){ maxVal[i][0] = atv[i][2]; maxVal[i][1] = atv[i][1]; for (int j = i; j >= 0; j--){ if (atv[i][0] >= maxVal[j][1] && maxVal[i][0] < maxVal[j][0] + atv[j][2]){ //可以接上前面的活动&&当前所有活动最大价值<前面所有活动最大价值 +当前活动价值 //接上活动,加上当前活动价值,更新最大价值结束点为当前活动结束点 maxVal[i][0] = maxVal[j][0] + atv[j][2]; maxVal[i][1] = atv[i][1]; break; } else if (atv[i][0] < maxVal[j][1] && maxVal[i][0] < maxVal[j][0]){ //不能接上前面活动&&当前活动最大价值<前面活动最大价值 //更新当前活动最大价值为前面活动的最大价值, maxVal[i][0] = maxVal[j][0]; maxVal[i][1] = maxVal[j][1]; } } } printf("%d,%d", maxVal[cnt - 1][0], maxVal[cnt - 1][1]); } return 0; }
相关文章推荐
- 算法导论-16.1-4 活动教室选择问题
- 活动选择问题的动态规划解
- 数据结构 练习 19-活动选择问题的实现(动态规划 和 贪心)
- 动态规划——贪心算法——活动选择问题 收藏
- 算法导论-第16章-贪心算法-16.1 活动选择问题
- 算法导论16.1 活动选择问题
- 算法导论-16.1-4 活动教室选择问题
- 《算法导论》笔记 第16章 16.1 活动选择问题
- 活动选择问题(动态规划和贪心算法)
- 算法导论16.1 活动选择问题
- 算法导论 16.1-1活动选择问题的动态规划算法 答案
- 动态规划(Dynamic programming,DP),通过把原问题分,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算量:
- 算法导论 第16章 活动选择问题的递归和迭代贪心算法
- 《算法导论》之动态规划和贪心算法 0-1背包问题
- 动态规划解决矩阵链乘问题的java编码实现
- 动态规划解决0-1背包问题
- 《算法导论》之 贪心算法—活动选择问题
- 贪心算法解决活动选择问题
- 动态规划解决航线设置问题