假定一个有n个活动(activity)的集合S={a1,a2,…,an},这些活动使用同一个资源(例如同一个阶梯教室),而这个资源在某个时刻只能供一个活动使用。每个活动ai都有一个开始时间si和一个结束时间fi,其中0<=si
#include
#include
#include
#include
using namespace std;
#define maxsize 1000
typedef long long ll;
int s[maxsize],f[maxsize],a[maxsize],n;
void init()
{
for(int i=1;i<=n;i++)
scanf("%d",&s[i]);
for(int i=1;i<=n;i++)
scanf("%d",&f[i]);
memset(a,0,sizeof(a));
}
void greed()
{
int cnt=0;
a[cnt++]=1;
k=1;
for(int m=2;m<=n;m++)
{
if(s[m]>=f[k])
{
a[cnt++]=m;
k=m;
}
}
}
void print()
{
for(int i=0;a[i]!='\0';i++)
printf("a%d",a[i]);
printf("\n");
}
int main()
{
while(~scanf("%d",&n))
{
init();
greed();
print();
}
}
分数背包与01背包问题不同点就是如果某物品无法被全部放入可以放入一部分
思路还是降序排列然后往背包添加
题目:
有 m 元钱,n 种物品;每种物品有 w 磅,总价值 v 元,
#include
#include
#include
using namespace std;
struct pack
{
double w;
double v;
int num;
bool operator<(const pack &a)const{
return (v/w)<(a.v/a.w);//最大值优先;
}
};
priority_queue<pack>q;
#define N 1000
int n;
double m,x[N];
double knapsack()
{
double sum=0;
for(int i=1;i<=n;i++) x[i]=0;
int i;
while(q.size()>0)
{
pack t=q.top();
if(t.w>m) break;
q.pop();
x[t.num]=1;
m-=t.w;
sum+=t.v;
}
if(q.size()!=0)
{
pack t=q.top();
q.pop();
x[t.num]=m/t.w;
sum+=t.v*x[t.num];
}
return sum;
}
int main()
{
scanf("%lf%d",&m,&n);
for(int i=1;i<=n;i++)
{
pack a;
scanf("%d%lf%lf",&a.num,&a.w,&a.v);
q.push(a);
}
double sum=knapsack();
printf("%lf",sum);
}
bool operator<(const pack &a)const{
return (v/w)<(a.v/a.w);//最大值优先;
}
}
这一部分return返回的总是a的值,这只能对于优先队列的排列
对于sort函数algorithm
#include //sort函数包含的头文件
typedef struct student
{
string name; //学生姓名
int achievement; //学生成绩
} student;
//这是函数是sort函数的第三个参数
//如果希望升序排序,就是"<",降序排列就是">"号
//如果希望用其他的参数作为排序条件,只需要把相应的条件改一下(如果改成name),这样结构体就以name作为排序标准
bool comparison(student a,student b){
return a.achievement<b.achievement;
}//成立返回前面
sort(sort(stu,stu+n,comparison);
假设要用很多个教室对一组活动进行调度。我们希望使用尽可能少的教室来调度所有的活动。请给出一个有效的贪心算法,来确定哪一个活动应使用哪一个教室。
(这个问题也被成为区间图着色(interval-graph coloring)问题。我们可作出一个区间图,其顶点为已知的活动,其边连接着不兼容的活动。为使任两个相邻结点的颜色均不相同,所需的最少颜色对应于找出调度给定的所有活动所需的最少教室数。)
#include
#include
#include
#include
using namespace std;
# define N 100
typedef struct A
{
int number; //活动编号
int begin; //活动开始时间
int end; //活动结束时间
bool flag; //此活动是否被选择
int roomnum; //此活动在哪间教室举行
}Activity;
bool cmp(Activity a,Activity b)
{
return a.end<b.end;
}
int select_room(Activity *a, int *time, int n)
{
int i = 1, j = 1;
//下面初始化数据,把第一个活动安排了,然后循环从第二个活动开始
int sumroom=1; //已经占用的教室,计算然后返回最终值
int sumact=1; //已经被选择的活动,初始化为1
time[1] = a[0].end; //初始化教室1的最后一个活动的结束时间为活动1的结束时间
a[0].roomnum = 1; //将第一个活动占用的教室初始化为教室1
for (i = 1; i < n; i++) //遍历i个活动
{
for(j=1;j<=sumroom;j++) //遍历j个教室,把活动i放进哪个教室
if (a[i].begin >= time[j] && (!a[i].flag)) //活动i开始的时间比教室j最后一个活动的结束时间晚,且活动i没有被规划过。那么就应该吧活动i划入教室j
{ //进行一波更新
a[i].roomnum = j;
a[i].flag = true;
time[j] = a[i].end;
sumact++;
}
if (sumact < n&&i == n - 1) //已经把一间教室能加入的活动搞完了,活动i不能已有加入教室,那么它就自己新开一间教室
{
i = 0; //控制重新遍历的条件
sumroom++;
}
}
return sumroom;
}
int main()
{
Activity a[N]; //定义一个结构体
int time[N]; //time 用于记录某个教室里面末尾活动的结束时间,方便与下一个活动的开始时间比较
int n,i=0,j; //输入的活动个数
int sum;
int k = 0;
scanf("%d", &n);
for (i = 0; i < n; i++)
{
time[i + 1] = 0;
a[i].number = i + 1;
a[i].flag = false;
a[i].roomnum = 0;
scanf("%d", &a[i].begin);
scanf("%d", &a[i].end);
}
sort(a,a+n,cmp);
sum=select_room(a,time,n);
printf("%d\n",sum);
for (i = 0; i < n; i++)
printf("%d->%d\n",a[i].number,a[i].roomnum);
}
#include
#include
#include
#include
using namespace std;
priority_queue<int,vector<int>, greater<int> > q;
int n,t,a,b;
long long sum=0;
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&t);
q.push(t);
}
if(q.size()==1)
{
sum+=q.top();
q.pop();
}
while(q.size()>1)
{
a=q.top();
q.pop();
b=q.top();
q.pop();
sum+=(a+b);
q.push(sum);
}
printf("%lld",sum);
}