最值求解,活动安排,部分背包问题

<p><strong>最值求解(<span style="font-family: 'Times New Roman';">MaxAndMin.cpp</span><span style="font-family: 宋体;">)</span></strong></p><p>【问题描述】</p><p>给定<span style="font-family: 'Times New Roman';">n</span><span style="font-family: 宋体;">个整数,编程求它们之中最大值和最小值,要求比较次数尽量小。</span></p><p>【输入】</p><p>输入文件<span style="font-family: 'Times New Roman';">MaxAndMin.in</span><span style="font-family: 宋体;">有两行,第</span><span style="font-family: 'Times New Roman';">1</span><span style="font-family: 宋体;">行包含一个整数</span><span style="font-family: 'Times New Roman';">n</span><span style="font-family: 宋体;">,表示输入的整数个数;第</span><span style="font-family: 'Times New Roman';">2</span><span style="font-family: 宋体;">行包含</span><span style="font-family: 'Times New Roman';">n</span><span style="font-family: 宋体;">整数,每个整数之间用一个空格隔开。</span></p><p>【输出】</p><p>输入文件<span style="font-family: 'Times New Roman';">MaxAndMin.out</span><span style="font-family: 宋体;">有两行,第</span><span style="font-family: 'Times New Roman';">1</span><span style="font-family: 宋体;">行包含一个整数,即为最小值;第</span><span style="font-family: 'Times New Roman';">2</span><span style="font-family: 宋体;">行包含一个整数,即为最大值。</span></p><p>【输入示例】</p><p>10</p><p>12 34 67 10 18 98 86 76 23 23</p><p>【输出示例】</p><p>10</p><p>98 </p>
#include <stdio.h>
#define N 1000
int x[N];
void pd(int r1,int r2, int &maxx,int &minn)      //二分法,r1是区间上界,r2是区间下界
{
	int max1,min1,max2,min2,d;  //d是区间的二分之一
	//************************************************
	if(r1==r2){
		maxx=minn=x[r1];
	}
	else if(r2==r1+1){
		if(x[r2]>x[r1]){
			maxx=x[r2];
			minn=x[r1];
		}
		else
		{
			maxx=x[r1];
			minn=x[r2];
		}
	}
	else
	{
		d=(r1+r2)/2;
		pd(r1,d,max1,min1);
		pd(d+1,r2,max2,min2);
		if(max1>max2)
			maxx=max1;
		else
			maxx=max2;
		if(min1<min2)
			minn=min1;
		else
			minn=min2;
	}







	//*******************************************
}
int main()
{ 
	int max=0,min=0,n,i;

	scanf("%d",&n);
	for(i=1;i<=n;i++)
		scanf("%d",&x[i]);
  pd(1,n,max,min);
	printf("%d\n",min);
    printf("%d\n",max);
	return 0;
}
使用二分法。

示例展示:



活动安排(Schedule.cpp

【问题描述】

假设有一个需要使用某一资源的n个活动所组成的集合S,S={1、…、n}。该资源一次只能被一个活动所占用,每一个活动有一个开始时间Bi和结束时间EiBi<=Ei)。若Bi>= EjBj>=Ei,则称活动i和活动j兼容。选择由互相兼容的活动所组成的最大集合,输出该集合的活动数量。

【输入】

输入文件Schedule.in有多行,第1行有1个正整数n,表示有n个待安排的活动。接下来的n行中,每行有2个正整数,分别表示n个待安排的活动的开始时间和结束时间。

【输出】

输入文件Schedule.out有一行,包含1个正整数,即计算的最多活动数。

【输入示例】

11

3   5

1   4

12  14

8   12

0   6

8   11

6   10

5   7

3   8

5   9

2   13

【输出示例】

4

#include <stdio.h>
struct ScType{
	int b;//活动开始时间
	int e;//活动结束时间
};
void swap(ScType &a,ScType &b) //交换a、b
{ 
	ScType temp;
	temp=a;
	a=b;
	b=temp;
}
void heapadjust(ScType *a,int s,int m) //堆排序
{
	ScType temp=a[s];
	for(int j=2*s;j<=m;j*=2){
		if(j<m && (a[j].e<a[j+1].e)) ++j;
		if(!(temp.e<a[j].e)) break;  
		a[s]=a[j];
		s=j;
	}
	a[s]=temp;
}

void heapsort(ScType *a,int m)
{
	int i; 
	for(i=m/2;i>0;--i) heapadjust(a,i,m);
	for(i=m;i>1;--i){
		swap(a[1],a[i]);
		heapadjust(a,1,i-1);
	}
}

int main()
{

	int n=0,i,k,sum=0;
  scanf("%d",&n);
  ScType *s=new ScType[n+1];
	int *r=new int[n+1];
	for (i=1;i<=n;i++){
		scanf("%d",&s[i].b);
		scanf("%d",&s[i].e);
		r[i]=0;
	}
	//******************************************************
	k=0;
	sum=0;
	heapsort(s,n);
	for(i=1;i<=n;i++)
	{
		if(k<=s[i].b)
		{
			k=s[i].e;
			r[i]+=1;
		}
	}
	for(i=1;i<=n;i++)
		if(r[i]==1)
			sum++;
		printf("%d",sum);






	//******************************************************
  delete []s;
	delete []r;
	return 0;
}


示例展示:



部分背包问题(PartBag.cpp

【问题描述】

给定一个最大载重量为M的卡车和N种食品,有食盐、白糖、大米等。已知第i种食品的最多有w[i]公斤,其商品价值为p[i]元/公斤,编程确定一个装货方案,使得装入卡车中的所有物品总价值最大。

【输入】

输入文件PartBag.in4行,第1行有1个正整数m,表示卡车的最大载重量;第2行有1个正整数n,表示食品的种类数;第3行有n个正整数,表示各种食品的公斤数;第4行有n个正整数,表示各种食品的单位价值。

【输出】

输入文件PartBag.out1行,包含1个正整数,表示装入卡车的所有物品的总价值。

【输入示例】

11

4

2 4 6 7

6 10 12 13

【输出示例】

139



#include <stdio.h>
struct ObjectType{
	int w;//重量
	int p;//价值
};
void swap(ObjectType &a,ObjectType &b)//交换a、b
{ 
	ObjectType temp;
	temp=a;
	a=b;
	b=temp;
}

void sort(ObjectType *a,int n)
{
  int i,j,k;
  for (i=1;i<=n-1;i++){
    k=i;
    for (j=i+1;j<=n;j++){
      if (a[j].p>a[k].p) k=j; 
    }
    if (k!=i) swap(a[k],a[i]);
  }
}

int main()
{

	int m=0,n=0,i,sum=0,c;
  scanf("%d",&m);
  scanf("%d",&n);
  ObjectType *ob=new ObjectType[n+1];
	int *r=new int[n+1];
	for (i=1;i<=n;i++){
		scanf("%d",&ob[i].w);
		r[i]=0;
	}
	for (i=1;i<=n;i++)
		scanf("%d",&ob[i].p);

	//******************************************************
	sort(ob,n);
	c=m;
	for(i=1;i<=n;i++)
	{
		if(c>=ob[i].w)
		{
			r[i]=1;
			c-=ob[i].w;
			sum+=(ob[i].w)*(ob[i].p);
		}
		else break;
	}
	sum+=c*ob[i].p;
	printf("%d",sum);





     
  
	//******************************************************
  delete []ob;
	delete []r;
	return 0;
}
示例展示:




That's all,thanks!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值