【算法笔记】动态规划 线性DP

关于动规:在这篇博客中,主要讲简单的线性DP.

1.最长上升子序列

题目:输出最长上升的子序列长度
思路:假设f[i]为第i个点的最长上升子序列的个数,那么我们只要找到比它小的最大值然后加上1即可,这是因为如果a[i]是这串序列最前边的数字,所以只要使排在这个数前面的数尽可能地多就好了,这就是这个算法这么做的原因了。

基本代码如下:

for (int i=1;i<=n;i++)
  {
  int maxx=0;
  for (int j=1;j<i;j++)//往前找最大值
    if (a[i]>a[j]) maxx=max(maxx,f[j]);//判断符合要求的数并求最大值
  f[i]=maxx+1;//求出第i个值的最长子序列
  }
程序如下:

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n,a[10000],f[10000]={};
	cin>>n;
	for (int i=1;i<=n;i++)cin>>a[i];
	for (int i=1;i<=n;i++)
	{
        int maxx=0;
        for (int j=1;j<i;j++)//往前找最大值
        if (a[i]>a[j]) 
		  maxx=max(maxx,f[j]);//判断符合要求的数并求最大值
        f[i]=maxx+1;//求出第i个值的最长子序列
    }
    int ans=-1;
    for (int i=1;i<=n;i++)
        if (f[i]>ans) ans=f[i];
    cout<<ans;
    return 0;
}
2.合唱队形

题目:N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK, 则他们的身高T1<...Ti+1>…>TK(1<=i<=K)。你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。

思路:通俗一点,这道题要求的就是求从小到大然后再从大到小的序列的长度(当然最后结果不是这个),假设这个最大点是i,所以i前面的是最长上升子序列,i的右边是最长下降子序列。那么这点想到了,这道题目的解法便一目了然了——我们便可以正反各求一遍最长上升子序列,使最大的某个点的左边右边的最长上升子序列接起来的和-1(减去本身)就是这个序列最长的长度了,最后进行处理一下就可以AC啦!

程序如下:

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n,a[10000],f1[10000]={},f2[10000]={};
	cin>>n;
	for (int i=1;i<=n;i++)cin>>a[i];
	for (int i=1;i<=n;i++)
	{
        int maxx=0;
        for (int j=1;j<i;j++)
        if (a[i]>a[j]) 
		  maxx=max(maxx,f1[j]);
        f1[i]=maxx+1;
    }//正
    for (int i=n;i>=1;i--)
	{
        int maxx=0;
        for (int j=n;j>i;j--)
        if (a[i]>a[j]) 
		  maxx=max(maxx,f2[j]);
        f2[i]=maxx+1;
    }//反
    int ans=1111111111;
    for (int i=1;i<=n;i++)
    ans=min(ans,n-(f1[i]+f2[i]-1));//求答案的最小值,即保留序列的最大值
    cout<<ans;
    return 0;
}

3.farmer john收苹果

题意:农场的夏季是收获的好季节。在Farmer John的农场,他们用一种特别的方式来收小苹果:Bessie摇小苹果树,小苹果落下,然后Farmer John尽力接到尽可能多的小苹果。作为一个有经验的农夫,Farmer John将这个过程坐标化。他清楚地知道什么时候(1<=t<=1,000,000)什么位置(用二维坐标表示,-1000<=x,y<=1000)会有小苹果落下。他只有提前到达那个位置,才能接到那个位置掉下的小苹果。一个单位时间,Farmer John能走s(1<=s<=1000)个单位。假设他开始时(t=0)站在(0,0)点,他最多能接到多少个小苹果?Farmer John 在接小苹果时,从某个点到另外一点按照直线来走

思路:这道题和上一道类似,首先在读入的时候应该按时间进行排序,f[i]表示的含义就是在第i个苹果摘的到的前提下找到苹果的最多数,做法和上一道一样(貌似要用到数学方法),最后输出即可。

#include<bits/stdc++.h>
using namespace std;
struct AC
{
	double x,y;
	int t;
}a[10000]={};
inline bool cmp(AC xx,AC yy)
{
	return xx.t<yy.t;
}
int main()
{
	int n,f[10000]={},ans=-1;
	double v;
	cin>>n>>v;
	for (int i=1;i<=n;i++)
	    cin>>a[i].x>>a[i].y>>a[i].t;
	sort(a+1,a+n+1,cmp);
	for (int i=1;i<=n;i++)
	{
		int maxx=0;
		if (f[i]==0&&sqrt(pow(a[i].x,2)+pow(a[i].y,2))>v*a[i].t) continue;//如何第i个点为第一个点并且无法到达
		for (int j=1;j<i;j++)
		    if (sqrt(pow(abs(a[j].x-a[i].x),2)+pow(abs(a[j].y-a[i].y),2))<=v*(a[i].t-a[j].t)
			    &&f[j]>maxx&&f[j]>0)
		        	maxx=f[j];
		f[i]=maxx+1;
	}
	for (int i=1;i<=n;i++)
	    ans=max(ans,f[i]);
	cout<<ans;
	//for (int i=1;i<=n;i++)cout<<endl<<f[i];
	return 0;
}




 




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
遗传算法可以用于解决线性规划问题。线性规划是一种数学优化问题,目标是在给定的线性约束条件下,找到使目标函数最大或最小的变量值。遗传算法通过模拟生物进化的过程来搜索最优解。在MATLAB中,可以使用遗传算法工具箱来解决线性规划问题。 首先,你需要了解遗传算法的原理和基本流程。遗传算法的原理和具体流程可以在各种书籍和资料中找到详细介绍\[1\]。在使用遗传算法工具箱时,你不需要深入理解其原理,因为这些已经封装在工具箱中。你只需要设定参数即可。 在MATLAB中,遗传算法工具箱提供了两个主要函数:gaoptimset()函数和ga()函数\[3\]。gaoptimset()函数用于设置遗传算法的参数,你可以根据具体问题进行调整。如果不设置参数,系统将使用默认值。ga()函数是调用遗传算法对优化问题进行计算。 对于线性规划问题,你需要将问题转化为标准形式。标准形式的线性规划问题包括一个目标函数和一组线性约束条件\[2\]。你可以使用MATLAB中的线性规划函数将问题转化为标准形式,然后使用ga()函数进行计算。 总结起来,使用MATLAB遗传算法工具箱解决线性规划问题的步骤如下: 1. 了解遗传算法的原理和基本流程\[1\]。 2. 将线性规划问题转化为标准形式\[2\]。 3. 使用gaoptimset()函数设置遗传算法的参数,根据具体问题进行调整。 4. 调用ga()函数进行遗传算法计算,得到最优解。 希望这个回答对你有帮助! #### 引用[.reference_title] - *1* *2* *3* [2021-04-26 Matlab遗传算法工具箱的使用及实例(线性规划)](https://blog.csdn.net/qingfengxd1/article/details/116176192)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值