zoukankan      html  css  js  c++  java
  • 华为0基础——合唱队

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

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

    编程思路是:须要三个数组。第一个数组存放原数据。第二个数组用于存放人数:从左向右遍历时,对于当前的数据(身高),寻找符合条件的人数。要求是从小到大排列的最大数。

    第三个数组用于存放人数:从右向左遍历,对于当前的数据。寻找符合条件的人数,要求从大到小排列的最大数。

    最后,通过第二个数组和第三个数组相应位置的数据之和,再减去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;
    }
    执行结果:


    总结:这是一道0基础题目。

    最開始看到这个题目的时候,真是毫无头绪,后来就想到找到最高的人,然后以这个人为中心。分别向前和向后遍历,事实上这样的思想本身就已经偏离了动态规划问题本身。找最高的人和他所在的位置。是不正确的。

    动态规划问题,是我值得弄明确的问题,希望通过一些简单的样例能够理清头绪。


  • 相关阅读:
    jdk1.5线程知识列表
    linux 常用命令记录
    spring batch 编码问题
    maven
    统计文本中每个单词出现的次数
    生成优惠券,并将优惠券存入Mysql
    python 2.7版本解决TypeError: 'encoding' is an invalid keyword argument for this function
    CSRF verification failed. Request aborted. 表单提交方法为POST时的报错
    InsecureRequestWarning: Unverified HTTPS request is being made.解决方法
    SQL Server 打印九九乘法表
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5075226.html
Copyright © 2011-2022 走看看