贪心算法

贪心算法例题
基本流程:决定贪心策略->得到局部最优解->得到全局最优解
最优装载问题

#include<iostream>
#include<algorithm>
const int N=10000;
using namespace std;
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<<"最多可装下";
    cout<<ans<<endl;
    return 0;
}

背包问题

#include<iostream>
#include<algorithm>
using namespace std;
const int N=10000;
struct three{
    double w;
    double v;
    double p;
}s[N];
bool cmp(three a,three b)
{
    return a.p>b.p;
}
int main()
{
    int n;
    double m;
    cout<<"输入宝物的数量n和毛驴的承载能力m"<<endl;
    cin>>n>>m;
    cout<<"逐个输入宝物的重量w和价值v"<<endl;
    for(int i=0;i<n;i++)
    {
        cin>>s[i].w>>s[i].v;
        s[i].p=s[i].v/s[i].w;
    }
    sort(s,s+n,cmp);
    double sum=0.0;
    for(int i=0;i<n;i++)
    {
        if(m>s[i].w)
        {
            m-=s[i].w;
            sum+=s[i].v;
        }
        else
        {
            sum+=m*s[i].p;
            break;
        }
    }
    cout<<"可装载最大价值"<<sum<<endl;
    return 0;
}

会议安排

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
struct Meet
{
    int beg;
    int end;
    int num;
}meet[100];
class setMeet{
    public:
    void init();
    void solve();
    private:
    int 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.beg<y.beg;
}
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"<<meet[i].beg<<"\t"<<meet[i].end<<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();
    return 0;
}

最短路径

#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;
bool flag[N];
void Dijkstra(int u)
{
	for(int i=1;i<=n;i++)
	{
		dist[i]=map[u][i];
		flag[i]=false;
		if(dist[i]==INF)
			p[i]=-1;
		else
			p[i]=u;
	}
	dist[u]=0;
	flag[u]=true;
	for(int i=1;i<=n;i++)
	{
		int  temp=INF,t=u;
		for(int j=i;j<=n;j++)
			if(!flag[j]&&dist[i]<temp)
			{
				t=j;
				temp=dist[j];
			}
		if(t==u) return;
		flag[t]=true;
		for(int j=1;j<=n;j++)
			if(!flag[j]&&map[t][j]<INF)
				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,no way"<<endl;
		else
			cout<<"最短距离为:"<<dist[i]<<endl;
	}
	return 0;
}

霍夫曼编码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
using namespace std;
#define MAXBIT 100
#define MAXVALUE 1000
#define MAXLEAF 30
#define MAXNODE MAXLEAF*2-1
typedef struct //定义节点
{
	double weight;
	int parent;
	int lchild;
	int rchild;
	char value;
}HNodeType;
typedef struct //定义编码类型
{
	int bit[MAXBIT]; //存储01编码的数组
	int start; //编码在数组中开始的位置,从最后往前减小
}HCodeType;
HNodeType HuffNode[MAXNODE]; //定义一个足够大的节点数组
HCodeType HuffCode[MAXLEAF]; 
void HuffmanTree (HNodeType HuffNode[MAXNODE],int n) //构造霍夫曼树
{
	int i,j,x1,x2;
	double m1,m2;
	for(i=0;i<2*n-1;i++) //初始化节点数据
	{
		HuffNode[i].weight = 0;
		HuffNode[i].parent = -1;
		HuffNode[i].lchild = -1;
		HuffNode[i].rchild = -1;
	}
	for(i=0;i<n;i++) //输入节点数据
	{
		cout<<"please input the value and weight of leaf node "<<i+1<<endl;
		cin>>HuffNode[i].value>>HuffNode[i].weight;
	}
	for(i=0;i<n-1;i++) //循环合并n-1次
	{
		m1=m2=MAXVALUE; 
		x1=x2=0;
		for(j=0;j<n+i;j++) //在已有的节点里找权重最小的且没有parent的节点
		{
			if(HuffNode[j].weight<m1&&HuffNode[j].parent==-1)
			{
				m2=m1;
				x2=x1;
				m1=HuffNode[j].weight;
				x1=j;
			}
			else if (HuffNode[j].weight<m2&&HuffNode[j].parent==-1)
			{
				m2=HuffNode[j].weight;
				x2=j;
			}
		} //最后m1,m2为最新权重节点的权重,x1,x2为其位置
		HuffNode[x1].parent=n+i;
		HuffNode[x2].parent=n+i;
		HuffNode[n+i].weight=m1+m2;
		HuffNode[n+i].lchild=x1;
		HuffNode[n+i].rchild=x2;
		cout<<"x1.weight and x2.weight in round "<<i+1<<"\t"<<HuffNode[x1].weight<<"\t"<<HuffNode[x2].weight<<endl;
	}
}
void HuffmanCode(HCodeType HuffCode[MAXLEAF],int n) //对生成的树进行编码
{
	HCodeType cd; //临时结构体
	int i,j,c,p;
	for(i=0;i<n;i++)
	{
		cd.start=n-1;
		c=i;
		p=HuffNode[c].parent; //p为遍历过程中每个节点的parent值
		while(p!=-1) //如果未到根节点
		{
			if(HuffNode[p].lchild==c) //为parent的左节点则在该处编码为0
				cd.bit[cd.start]=0;
			else
				cd.bit[cd.start]=1;
			cd.start--; //编码长度加1,start位置减1
			c=p;
			p=HuffNode[c].parent;
		}
		for(j=cd.start+1;j<n;j++)
			HuffCode[i].bit[j]=cd.bit[j]; 
		HuffCode[i].start=cd.start; //将临时变量复制到编码结构体
	}
}
int main()
{
	int i,j,n;
	cout<<""<<endl;
	cin>>n;
	HuffmanTree(HuffNode,n);
	HuffmanCode(HuffCode,n);
	for(i=0;i<n;i++)
	{
		cout<<HuffNode[i].value<<" :Huffman code is: ";
		for(j=HuffCode[i].start+1;j<n;j++)
			cout<<HuffCode[i].bit[j];
		cout<<endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值