贪心算法(C++描述)

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1000005;
double w[N];

int main()
{
	double c;
	int n;
	cout << "请输入载重量c及古董个数n: " << endl;
	cin >> c >> n;
	cout << "请输入每个古董的重量 " << endl;
	for (int i = 0;i < n;i++)
	{
		cin >> w[i];
	}
	sort(w, w + n);
	double temp = 0.0;
	int ans = 0;
	for (int i = 0;i < n;i++)
	{
		temp += w[i];
		if (temp <= c)
			ans++;
		else
			break;
	}
	cout << "能装入的古董最大数为Ans=";
	cout << ans << endl;

	system("pause");
	return EXIT_SUCCESS;
}

判断是不是刚好用完空间

优化,首先用变量ans记录已经装载的古董个数,初始化为n;tmp代表装载到船上的古董的重量,初始化为0。改进为判断加上最后一个宝藏是不是等于背包容量

int tmp = 0,ans = n;
for(int i=0;i<n;i++)
{
	temp += w[i];
	if(temp>=c)
	{
		if(temp==c)
			ans = i+1;
		else
			ans = i;
		break;
	}
}

在这里插入图片描述使用C++中的sort函数
sort(begin,end)//参数begin和end表示一个范围,分别为待排序数组的首地址和尾地址。

#include <iostream>
#include <algorithm>
using namespace std;
const int M = 1000005;

struct three {
	double Weight; //每个宝物的重量
	double Value; //每个宝物的价值
	double price; //性价比
}s[M];

bool cmp(three a, three b)
{
	return a.price > b.price; //根据宝物的性价比从大到小排序
}


int main()
{
	int n; //n个宝物
	double m; //驴子的承载能力
	cout << "请输入宝物数量n和驴子的承载能力m " << endl;
	cin >> n >> m;
	cout << "输入每个宝物的重量和价值" << endl;
	for (int i = 0;i < n;i++)
	{
		cin >> s[i].Weight >> s[i].Value;
		s[i].price = s[i].Value / s[i].Weight;
	}
	sort(s, s + n, cmp);
	double sum = 0.0;
	for (int i = 0;i < n;i++)
	{
		if (m > s[i].Weight)
		{
			m -= s[i].Weight;
			sum += s[i].Value;
		}
		else
		{
			sum += m * s[i].price;
			break;
		}
	}
	cout << "装入的最大价值为" << sum << endl;
	system("pause");
	return EXIT_SUCCESS;
}

但是在物品不可分割,没法装满的情况下,贪心算法并不能获得最优解,仅仅是最优解的近似解。
物品可分割的装载问题我们称为背包问题,物品不可分割的问题我们称为0-1背包问题
物品不可分割的情况下,原问题的整体最优解无法通过一系列局部最优解选择得到。因此这类问题得到的是近似最优解。

开会时间的贪心算法

在这里插入图片描述

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
struct Meet
{
	int beg;//会议开始时间
	int end;//会议结束时间
	int num;//记录会议的编号
}meet[1000]; //会议的最大个数为1000

class setMeet
{
public:
	void init();
	void solve();
private:
	int n, ans; //n:会议总数 ans:最大的安排会议总数
};

void setMeet::init()
{
	int s, e;
	cout << "请输入会议总数: " << endl;
	cin >> n;
	int i;
	cout << "请输入会议的开始和结束时间,以空格分开 " << endl;
	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.end)
		return x.beg > y.beg;
	return x.end < y.end;
}

void setMeet::solve()
{
	sort(meet, meet + n, cmp);
	cout << "排序完的会议时间如下: " << endl;
	int i;
	cout << "会议编号" << "开始时间" << "结束时间" << endl;
	for (i = 0; i < n; i++)
	{
		cout << " " << meet[i].num << "\t\t" << meet[i].beg << "\t" << meet[i].end << endl;
	}
	cout << "---------------------------------" << endl;
	cout << "选择的会议的过程: " << endl;
	cout << " 选择第" << meet[0].num << "个会议" << endl;
	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 <<"个会议"<<endl;
		}
	}
	cout << "最多可以安排" << ans <<"个会议"<< endl;
}

int main()
{
	setMeet sm;
	sm.init();
	sm.solve();
	system("pause");
	return EXIT_SUCCESS;
}

迪杰斯特拉

#include <cstdio>
#include <iostream>
#include <cstring>
#include <windows.h>
#include <stack>
using namespace std;
const int N = 100;
const int INF = 1e7;
int map[N][N], dist[N], p[N], n, m; //n为城市的个数,m为城市间线路的条数
bool flag[N];//如果flag[i]等于true,说明顶点i已经加入到集合S,否则顶点i术语集合V-S
void Dijkstra(int u)
{
 for (int i = 1;i <= n;i++)
 {
  dist[i] = map[u][i];//初始化源点u到其他各个顶点的最短路径长度
  flag[i] = false;
  if (dist[i] == INF)
   p[i] = -1; //源点u到顶点的路径长度为无穷大,说明顶点i与源点u不相邻
  else
   p[i] = u;//说明顶点i与源点u相邻,设置顶点i的前驱p[i]=u;
 }
 dist[u] = 0;
 flag[u] = true; //初始时,集合s中只有一个元素:源点u
 for (int i = 1;i <= n;i++)
 {
  int temp = INF, t = u;
  for (int j = 1;j <= n;j++) //在集合V-S中寻找距离源点u最近的顶点t
  {
   if (!flag[j] && dist[j] < temp)
   {
    t = j;
    temp = dist[j];
   }
  }
   if (t == u) return; //找不到t 跳出循环
   flag[t] = true; //否则,将t加入集合
   for (int j = 1;j <= n;j++) //更新v-s中与t邻接的顶点到源点u的距离
    if (!flag[j] && map[t][j] < INF) //!s[j]表示j在V-S中
     if (dist[j] > (dist[t] + map[t][j]))
     {
      dist[j] = dist[t] + map[t][j];
      p[j] = t;
     }  
 }
}
int main()
{
 int u, v, w, st;
 system("color 0d");
 cout << "请输入城市的个数: " << endl;
 cin >> n;
 cout << "请输入城市之间的路线的个数: " << endl;
 cin >> m;
 cout << "请输入城市之间的路线以及距离: " << endl;
 for (int i = 1;i <= n;i++)
 {
  for (int j = 1;j <= n;j++)
  {
   map[i][j] = INF;
  }
 }
 while (m--)
 {
  cin >> u >> v >> w;
  map[u][v] = min(map[u][v], w); 
 }
 cout << "请输入小明所在的位置"<< endl;
 cin >> st;
 Dijkstra(st);
 cout << "小明所在的位置: " << st << endl;
 for (int i = 1;i <= n;i++)
 {
  cout << "小明: " << st << " - " << "要去的位置: " << i << endl;
  if (dist[i] == INF)
   cout << "Sorry,无路可达" << endl;
  else
   cout << "最短距离为:" << dist[i] << endl;
 }
 
 system("pause");
 return EXIT_SUCCESS;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值