码迷,mamicode.com
首页 > 其他好文 > 详细

华为初级——合唱队

时间:2014-06-26 08:19:13      阅读:305      评论:0      收藏:0      [点我收藏+]

标签:class   blog   code   http   ext   数据   

bubuko.com,布布扣

提示:这是属于动态规划问题。动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。

其实这道题目有一些问题:不能交换位置,这个关键的信息在题目中间没有进行说明。

编程思路是:需要三个数组,第一个数组存放原数据。第二个数组用于存放人数:从左向右遍历时,对于当前的数据(身高),寻找符合条件的人数,要求是从小到大排列的最大数。第三个数组用于存放人数:从右向左遍历,对于当前的数据,寻找符合条件的人数,要求从大到小排列的最大数。最后,通过第二个数组和第三个数组对应位置的数据之和,再减去1,来求得最佳解。

问题有待解决:我们只能得到最优解的人数,但是不能得到是那些人组成了合唱队。不过我发现这是动态规划问题普遍存在的现象。

源程序如下:

#include <iostream>
using namespace std;

const int maxn = 100 + 1;

int main()
{
	int n;
	int a[maxn];
	int f1[maxn];//存放合唱队的人数(从左向右)
	int f2[maxn];//存放合唱队的人数(从右向左)

	cin>>n;
	for(int i=1;i<=n;i++)//第0个位置不存放数据,符合平常的思维习惯。
		cin>>a[i];

	for(int i=1;i<=n;i++)//由左向右依次遍历 
	{	
		f1[i] = 1;//至少有一个人符合条件,就是他自己。所以赋初值1.
		for(int j=1;j<i;j++)	
		{
			if(a[i]>a[j]&&f1[i]<f1[j]+1) //f1[i]<f1[j]+1很关键的条件,动态问题
				f1[i]= f1[j]+1;
		}		 
	}

	for(int i=n;i>=1;i--)//由右向左依次遍历
	{
		f2[i] = 1;//至少有一个人符合条件,就是他自己。所以赋初值1.	
		for (int j=i+1;j<=n;j++)	
		{		
			if(a[i]>a[j]&&f2[i]<f2[j]+1) 		
				f2[i]=f2[j]+1;	
		}
	}

	int ans = 0;
	for(int i=1;i<=n;i++)
		if(ans<f1[i]+f2[i]-1) 
			ans=f1[i]+f2[i]-1;//最佳解
	cout<<n-ans<<endl;//需要出列的人数
	return 0;
}
运行结果:

bubuko.com,布布扣

总结:这是一道初级题目。最开始看到这个题目的时候,真是毫无头绪,后来就想到找到最高的人,然后以这个人为中心,分别向前和向后遍历,其实这种思想本身就已经偏离了动态规划问题本身。找最高的人和他所在的位置,是不对的。动态规划问题,是我值得弄明白的问题,希望通过一些简单的例子可以理清头绪。


华为初级——合唱队,布布扣,bubuko.com

华为初级——合唱队

标签:class   blog   code   http   ext   数据   

原文地址:http://blog.csdn.net/xmh1954/article/details/34422349

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!