user-0 提问: 新手求这题算法

回复:
user: user-1
content: 直接DP, d[i][j][k] 代表从i天到j天中买k次股票的最大利润 1 ) 初始 d[i][j][k]=0, d[i][i+1][1]=a[i+1]-a[i] 2) 3重循环  i<=k<j                   d[i][j][1]=max(d[i][k][1],d[k][j][1])                   d[i][j][2]=max(d[i][k][2],d[k][j][2],d[i][k][1]+d[k][j][1])  答案为d[0][n-1][2]

user: user-2
content: ans=0 for (int i=0;i<n;i++)  {     max1=0     for (int j=0;j<i;j++)     {         for (int h=j+1;j<i;j+)         {             if (max1<a[h]-a[j])                 max1=a[h]-a[j]         }     }     max2=0     for (int j=i;j<n;j++)     {         for (int h=j+1;j<i;j+)         {             if (max2<a[h]-a[j])                 max2=a[h]-a[j]         }     }     if (ans<max1+max2)         ans=max1+max2 } 用i把数据分为两段，每段用上面的算法求最大收益，复杂度O（n^3)1000个数勉强能接受

user: user-0
content: 引用 12 楼 fly_dragon_fly 的回复:直接DP, d[i][j][k] 代表从i天到j天中买k次股票的最大利润 1 ) 初始 d[i][j][k]=0, d[i][i+1][1]=a[i+1]-a[i] 2) 3重循环  i<=k<j                   d[i][j][1]=max(d[i][k][1],d[k][j][1])                   d[i][j][2]=max(d[i][k][2],d[k][j][2],d[i][k][1]+d[k][j][1])  答案为d[0][n-1][2] 智商有限，听不懂a<(*￣▽￣*)/

user: user-2
content: 引用 9 楼 liehu232的回复:[quote=引用 8 楼 o_ollll的回复:][quote=引用 6 楼 liehu232 的回复:] [quote=引用 3 楼 liehu232的回复:]for (int i = 0; i < n; i++)  { 	max[i]=0; 	for (int j = i + 1; j < n; j++) 	{ 		if (max[i] < a[j]-a[i]) 		{ 			max[i] = a[j] - a[i]; 		} 	} } max最大两个数之和 O(n2)1000个数肯定不会超时 解释一下我的算法max数组保存第i天买入股票可以获得的最大收益，第i天买入股票后扫描之后第i+1天到第n天卖出所获得收益，max数组保存最大值，最后取max数组最大的两个值，就是两次买入股票能获得的最大收益[/quote]  比如输入 14 1 10 5 13 8 17 11 15 5 12 9 20 2 15           最大为20-1+15-2=32   你的算法是20-0+20-5 错了吧。。。a︿(￣︶￣)︿[/quote] 题目直只说一天可以买一次，没说不可以同一天卖明显我的算法收益高。如果考虑不能同一天卖出，就要两次循环，第二次循环排除第一次的买卖点，就是你的结果了[/quote] 没看清题目，同时只能持有一支股票，那我的算法就不对了

user: user-2
content: 引用 8 楼 o_ollll的回复:[quote=引用 6 楼 liehu232 的回复:] [quote=引用 3 楼 liehu232的回复:]for (int i = 0; i < n; i++)  { 	max[i]=0; 	for (int j = i + 1; j < n; j++) 	{ 		if (max[i] < a[j]-a[i]) 		{ 			max[i] = a[j] - a[i]; 		} 	} } max最大两个数之和 O(n2)1000个数肯定不会超时 解释一下我的算法max数组保存第i天买入股票可以获得的最大收益，第i天买入股票后扫描之后第i+1天到第n天卖出所获得收益，max数组保存最大值，最后取max数组最大的两个值，就是两次买入股票能获得的最大收益[/quote]  比如输入 14 1 10 5 13 8 17 11 15 5 12 9 20 2 15           最大为20-1+15-2=32   你的算法是20-0+20-5 错了吧。。。a︿(￣︶￣)︿[/quote] 题目直只说一天可以买一次，没说不可以同一天卖明显我的算法收益高。如果考虑不能同一天卖出，就要两次循环，第二次循环排除第一次的买卖点，就是你的结果了

user: user-0
content: 引用 6 楼 liehu232 的回复:[quote=引用 3 楼 liehu232的回复:]for (int i = 0; i < n; i++)  { 	max[i]=0; 	for (int j = i + 1; j < n; j++) 	{ 		if (max[i] < a[j]-a[i]) 		{ 			max[i] = a[j] - a[i]; 		} 	} } max最大两个数之和 O(n2)1000个数肯定不会超时 解释一下我的算法max数组保存第i天买入股票可以获得的最大收益，第i天买入股票后扫描之后第i+1天到第n天卖出所获得收益，max数组保存最大值，最后取max数组最大的两个值，就是两次买入股票能获得的最大收益[/quote]  比如输入 14 1 10 5 13 8 17 11 15 5 12 9 20 2 15           最大为20-1+15-2=32   你的算法是20-0+20-5 错了吧。。。a︿(￣︶￣)︿

user: user-3
content: 的确，想的简单了，不过这不失为一种优化方案，把无用数据去除了， 再用那些O(n^2)的算法也可以降低处理时间.

user: user-2
content: 引用 3 楼 liehu232的回复:for (int i = 0; i < n; i++)  { 	max[i]=0; 	for (int j = i + 1; j < n; j++) 	{ 		if (max[i] < a[j]-a[i]) 		{ 			max[i] = a[j] - a[i]; 		} 	} } max最大两个数之和 O(n2)1000个数肯定不会超时 解释一下我的算法max数组保存第i天买入股票可以获得的最大收益，第i天买入股票后扫描之后第i+1天到第n天卖出所获得收益，max数组保存最大值，最后取max数组最大的两个值，就是两次买入股票能获得的最大收益

user: user-0
content: 引用 4 楼 user-3 的回复:[quote=引用 2 楼 o_ollll 的回复:] 还是不懂。。。┑(￣Д ￣)┍  比如10    1 10 2 10 1 10 1 20 0 10  怎么弄啊。。  极小数就是比前后两个数都小，极大数就是比前后都大。  10    1 10 2 10 1 10 1 20 0 10  中  1 是极小数，10是极大数，2是极小数，10是极大数，1是极小数，20是极大数。。。。。 居然没有中间数，太特殊了。 这样第一组是10-1 = 9.，第二组，10-2=8，第三组19，第四组10，最高两组是19和10. 也就是选择1买进，20卖出，0买进(0的话怎么买┑(￣Д ￣)┍). 10卖出，获利29[/quote]  那么再来一个例子 10          10 12 11 13 12 14 13 20 1 10          这么明显最大是20-10+10-1，你那个是不是弄错了

user: user-3
content: 引用 2 楼 o_ollll 的回复:还是不懂。。。┑(￣Д ￣)┍  比如10    1 10 2 10 1 10 1 20 0 10  怎么弄啊。。  极小数就是比前后两个数都小，极大数就是比前后都大。  10    1 10 2 10 1 10 1 20 0 10  中  1 是极小数，10是极大数，2是极小数，10是极大数，1是极小数，20是极大数。。。。。 居然没有中间数，太特殊了。 这样第一组是10-1 = 9.，第二组，10-2=8，第三组19，第四组10，最高两组是19和10. 也就是选择1买进，20卖出，0买进(0的话怎么买┑(￣Д ￣)┍). 10卖出，获利29

user: user-3
content: 可以抽像化，把这些点连起来看作曲线， 这道题变成在函数图像中，选取(最多)两段使其相加高度最高，可以想象:    选取点以极小值点做为起点，极大值点做为终点，一次遍历就能把极大极 小值选出来，第二次遍历选最高的两段。这两次遍历应该可以合并， 时间复杂度O(n), 1000ms都太多了.

user: user-2
content: for (int i = 0; i < n; i++)  { 	max[i]=0; 	for (int j = i + 1; j < n; j++) 	{ 		if (max[i] < a[j]-a[i]) 		{ 			max[i] = a[j] - a[i]; 		} 	} } max最大两个数之和 O(n2)1000个数肯定不会超时

user: user-0
content: 还是不懂。。。┑(￣Д ￣)┍  比如10    1 10 2 10 1 10 1 20 0 10  怎么弄啊。。