【我的创作纪念日】C++进阶,一篇就够了

 本文图片和部分材料来源网络,如有侵权,请联系我删除,谢谢!

一.贪心

现在我们来学习贪心:

1.贪心是什么?

贪心算法(Greedy Algorithm)是一种基于贪心思想的算法策略。它通过每一步选择当前状态下最优的解决方案,从而逐步得到全局最优解

贪心算法的步骤:

1、确定问题的最优子结构

2、定义(每一步)贪心选择策略

3、构建方案及验证方案

那么,我们先讲一道例题吧!

看完题目,你觉得它的贪心策略是什么? 

这里做一个投票(在最下面,题目为 “ 单项选择题(1)贪心策略是什么?” )

好了这里的正确答案是A

因为节水总时长要少,那么就要先让接水时间少的先接水(注意,这里说了t[i]可能会重复)

这里我们需要用到结构体,所以需要写一个排序规则的函数(函数文章指路):

struct w{
	int id,b;
}a[1005];
bool cmp(w x,w y)
{
	if(y.b==x.b)
	{
		return x.id<y.id;
	}
	return x.b<y.b;
}

那么接下来,我们 来写输入输出以及排序:

int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i].b;
		a[i].id=i;
	}
	sort(a+1,a+1+n,cmp);

 这里有一个坑,末尾不能输出空格(好雷),错了不知道多少次

(我用的方法是:先输出第一个,然后输出空格,再输出其他的)

输出部分:

    cout<<a[1].id;
	double s=a[1].b;
	for(int i=2;i<=n;i++)
	{
		cout<<" "<<a[i].id;
		sum+=s;
		s+=a[i].b;
	}
	cout<<endl;
	printf("%.2lf",sum/n);

 完整代码:

#include<bits/stdc++.h>
using namespace std;
double sum=0.0;
struct w{
	int id,b;
}a[1005];
bool cmp(w x,w y)
{
	if(y.b==x.b)
	{
		return x.id<y.id;
	}
	return x.b<y.b;
}
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i].b;
		a[i].id=i;
	}
	sort(a+1,a+1+n,cmp);
	cout<<a[1].id;
	double s=a[1].b;
	for(int i=2;i<=n;i++)
	{
		cout<<" "<<a[i].id;
		sum+=s;
		s+=a[i].b;
	}
	cout<<endl;
	printf("%.2lf",sum/n);
	return 0;
}

那么,简单的贪心,你学会了嘛? 

留一道习题:

二.动态规划

我们知道,动态规划有很多类型

现在我们来讲解——最长上升子序列!

动态规划简称 DP/dp(dynamic programming

题目

在学习动态规划之前,我们要先学会几个步骤:

1.把一个大问题拆分成多个小问题

2.推导状态转移方程

3. 考虑边界问题

那么,这道题的状态转移方程是什么呢?

(如果前面任意一个数比现在我们搜索的数小,并且是比我们现在搜索的数小里面,下方数值最多的,那么这个数下方的数值=下方数值最多的) 

13  7  91638243718441921226315
11234454667873

不难发现,状态转移方程是:

dp[i]=max(dp[i],dp[j]+1);

注:如果用我的思路的话,在第一层循环结束时还要判一次最大值!

代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,a[1005],dp[1005],mxx=0;
    cin>>n;
    dp[1]=1;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    for(int i=1;i<=n;i++)
    {
        dp[i]=1;
        for(int j=1;j<i;j++)
        {
            if(a[i]>a[j])
            {
                dp[i]=max(dp[i],dp[j]+1);
            }
        }
        mxx=max(dp[i],mxx);
    }
    cout<<mxx;
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值