算法设计与分析_01

【学习通】

选择

【编程题】

要求

交电子版,命名格式:学号-姓名。包含代码、测试数据、程序截图。

贪心法

简述贪心法的基本思想、特点、求解过程。

基本思想:保证每次都是局部最优解,从而使全局接近最优。
特点:可以解决贪心选择性质和最优子结构性质问题的最优解问题。
求解过程:从某个初始解出发,采用迭代的过程,当可以向目标前进一步时,就根据局部最优策略,得到一部分解,缩小问题规模,将所有解综合起来得到最优解。

使用贪心法,编程实现会议安排问题。

#include <iostream>
#include <alogorithm>
#include <cstring>
using namespace std;
struct Meet
{
    int beg;
    int end;
    int num;
} meet[1000];
class setMeet{
    public:
     void init();
     void solve();
    private:
     int n,ans;
}
void setMeet::init()
{
    int s,e;
    cout<<"输入会议总数:"<<end1;
    cin>>n;
    int i;
    cout<<"输入会议的开始时间和结束时间,以空格分开"<<end1;
    for(i=0;i<n;i++)
    {
        cin>>s>>e;
        meet[i].beg=s;
        meet[i].end=e;
        meet[i].num=i+1;
    }
}
bool cmp(Meet x,Meet y)
{
    if(x.end==y.beg)
        return x.beg>y.beg;
    return x.beg<y.beg;
}
void setMeet::solve()
{
    sort(meet,meet+n,cmp);
    cout<<"排完序的会议时间如下:"<<end1;
    int i:
    cout<<"会议编号"<<"开始时间"<<"结束时间"<<end1;
    for(i=0;i<n;i++)
    {
        cout<<"  "<<meet[i].num<<"\t\t"<<meet[i].beg<<"\t"<<meet[i].end<<end1;
    }
    cout<<"-----------------------------------------------------------"<<end1;
    cout<<"选择的会议的过程:"<<end1;
    cout<<"选择第"<<meet[0].num<<"个会议"<<end1;
    ans=1;
    int last=meet[0].end;
    for(i=1;i<n;i++)
    {
        if(meet[i].beg>=last)
        {
            ans++;
            last=meet[i].end;
            cout<<"选择第"<<meet[i].num<<"个会议"<<end1;
        }
    }
}
int main()
{
    setMeet sm;
    sm.init();
    sm.slove();
    return 0;
}

分治法

简述分治法的基本思想、特点、求解过程。

基本思想:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
特点:将问题分解为若干个相同的子问题,降低问题的解决难度。

使用分治法,编程找出n个数中第k小的数字。

#include <iostream>
 
using namespace std;
 
int partition(int[], int, int);
int Select(int[], int, int, int); 
 
int main()
{
	int n, m;
	int l, r, k;
	int v[100002];
	int d[100002];
	cin >> n >> m;
	for (int i = 1; i <= n; i++) cin >> v[i];
	while (m--)
	{
		cin >> l >> r >> k;
		for (int j = l; j <= r; j++) d[j] = v[j];
		cout << Select(d, l, r, k) << endl;
	}
 	return 0;
}
 
//一次快速排序 
int partition(int s[], int l, int r)
{
	if (l < r)
	{
		int i = l;
		int j = r;
		int x = s[i];
		while (i < j)
		{
			while (i < j && s[j] >= x) j--;
			if (i < j) s[i++] = s[j];
			while (i < j && s[i] < x) i++;
			if (i < j) s[j--] = s[i];
		}
		s[i] = x;
		return i;
	}
	return -1;
}
 
//分治找K-th Number 
int Select(int s[], int l, int r, int k)
{
	if (l > r) return -1;
	if (l == r) return s[l];
	//得到中间数的下标 
	int i = partition(s, l, r);
	//j为左区间长度 
	int j = i - l + 1;
	//位置大就在左区间找,否则就在右区间找
	if (j == k) return s[i];
	else if (j > k) return Select(s, l, i, k);
	else return Select(s, i+1, r, k-j);
}

动态规划法

动态规划法的特点是什么?它能解决哪一类问题?

编写程序,找出让两个字符串S1、S2最快变一致的方法,输入测试数据,写出测试结果。

编写程序,解决0-1背包问题,输入测试数据,写出测试结果。

posted @ 2021-09-17 09:10  πππ  阅读(20)  评论(0)    收藏  举报