2102:合并果子
#include<bits/stdc++.h> 
int n,a[10005],ans;
int main()
{
	scanf("%d",&n);
	for(int i=0;i< n;i++){ 
		scanf("%d",&a[i]);
	} 
	std::sort(a,a+n);
	for(int i=1;i< n;i++){
		ans += a[i-1]+a[i]; 
		a[i]=a[i-1]+a[i];
		for(int j=i+1;j<n;j++)
		{
			if(a[j-1]>a[j]) std::swap(a[j-1],a[j]); 
			else break;
		}
	}
	printf("%d",ans);
    return 0;
}

优先队列做法

//队列:将最小的拿出之后在将合并后的推入如此反复 
#include<bits/stdc++.h>
using namespace std;
priority_queue<int,vector<int>,greater<int> >fruit; //优先队列,自动让队列中的元素由小到大排序 
int main()
{
    int n;
    int total=0;//力气总量 
    int temp=0;
    int theweightoffruit;//果子的重量 
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d",&theweightoffruit);
        fruit.push(theweightoffruit);//每输入一个果子的重量,他将由小到大排序 
    }
    for(int i=0;i<n-1;i++){
        temp=fruit.top();//弹出顶部元素,即最小的一堆 
        fruit.pop();//弹出当前最小的元素 
        temp+=fruit.top();//读取当前最小的一堆并与前一个元素合并 
        fruit.pop();//弹出第二小的元素 
        fruit.push(temp);//再将合并后的元素压入队列中 
        total+=temp;//那么花费的总力气再加上盒子里的就可以 
    }
    printf("%d",total);
    return 0;
}
2115: 区间选点(贪心)
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL  ed,sum,n;
struct node{
    LL l,r;
}a[100001];
//以右边界进行区间排序,并开始遍历区间 
bool cmp(node x,node y){
	return x.r<y.r; 
} 
int main(){
    cin>>n;
    for (int i = 1; i <= n; i++) {
        cin>>a[i].l>>a[i].r;
    }
    sort(a+1,a+n+1,cmp); 
    //初始点ed=a[1].r sum=1 
    ed=a[1].r; sum=1; 
    for (int i = 1; i <= n; i++) 
	{
		//用ed判断和a[i].l大小
		//ed>a[i].l 说明该点能包含这个区间
		//ed<a[i].l 说明该点包含不了 
		//ed=a[i].r sum++  
		if(ed<a[i].l)
		{
			sum++;
			ed=a[i].r;
		 }   
	}  
   cout<<sum; 
   return 0; 
}
2081: 盛水问题
#include<bits/stdc++.h>
using namespace std;  
int n,height[105],maxWater; 
int main() {  
    cin>>n;
	for(int i=0;i<n;i++)
		cin>>height[i];
	//双指针  
	int left = 0;//左指针,初始指向数组的第一个元素  
	int right = n - 1; //右指针,初始指向数组的最后一个元素   
	// 当左指针小于右指针时,执行循环 ,否则指针无法移动 
	while (left < right) {  
		//获取当前两个指针所指向的垂线构成的容器的水量 
        int currentArea =  min(height[left], height[right]) * (right - left);  
        // 更新最大水量(如果当前水量大于已知的最大水量) 
        maxWater =  max(maxWater, currentArea);  
		// 判断哪个指针应该移动  
        // 如果左指针的高度小于右指针的高度,则移动左指针  
        // 因为如果移动右指针,新的高度一定不大于当前左指针的高度,而宽度又减小了,所以水量不可能增加 
        if (height[left] < height[right]) {  
            ++left; // 移动左指针  
        } else {  
            --right; // 移动右指针  
        }  
    }  
	cout<<maxWater; 
    return 0;  
}
1467: 【例85.1】 金银岛
#include <bits/stdc++.h>// 引用万能头文件
using namespace std;//  标准命名空间
//金银岛问题 
/*
	1、计算性价比  总价/总重 
	2、性价比排序  sort(性价比) 
	3、装入口袋 
	4、输出ans 
*/ 

struct Node{
	int w;//总重量 
	double all_p;//总价 
	double p; //单价 
}a[105]; 
int n;
int p(Node n1,Node n2)
{
	return n1.p>n2.p;
}
int main() {
  	cin>>n; 
  	int b,s;
  	for (int i=1;i<=n;i++){
  		double 	ans=0;
  		cin>>b>>s;
  		for(int j=1;j<=s;j++){
  			cin>>a[j].w>>a[j].all_p;
  			a[j].p = a[j].all_p/(a[j].w*1.0);
		  }
		  sort(a+1,a+1+s,p);
		  int n=1;
		  while((b-a[n].w)>=0&&n<=s)
		  {
		  	ans+=a[n].all_p;
		  	b-=a[n].w;
		  	n++;
		  }
		  if(b<a[n].w&&n<=s)
		  	ans +=b*a[n].p;
		printf("%.2lf\n",ans);
	  }
	return 0;
}
2053: 楼间跳跃
#include<bits/stdc++.h>
using namespace std;
long long n,m;
struct node {
    long long h;
    long long v;
    //重置小于号运算符
    bool operator < (const node &x) const{
        return v>x.v;//这里反写,保证默认为小根堆
    }
};
node a[1000005];
priority_queue <node> q;//小根堆,维护拿走的价值
long long ans=0;
long long sum=0;//拿走的价值总数
long long cnt=0;//拿走的楼层总数
int main() {
    cin>>n>>m;
    m++;//加上第一步
    for(int i=1;i<=n;i++){
        cin>>a[i].h>>a[i].v;
        a[i].h--;//去掉进入该楼的层
    }
    for(int i=1;i<=n;i++){
        if (i>m) break;//达不到i栋楼
        sum+=a[i].v;//进入第i栋楼拿走的第一个v
        if (a[i].h>0){//还有没拿走的
            sum+=a[i].v*a[i].h;//都拿走
            q.push(a[i]);//入队
            cnt+=a[i].h;//都加进去
        }
        while (q.size()&&cnt-q.top().h>=m-i){//多的减掉
            cnt-=q.top().h;
            sum-=q.top().h*q.top().v;
            q.pop();
        }
        if (cnt>m-i){//如果还多
            ans=max(ans,sum-q.top().v*(cnt-(m-i)));
        }else{//不多
            ans=max(ans,sum);
        }
    }
    cout<<ans;
    return 0;
}
1471: 练85.2 排队接水
#include <bits/stdc++.h>
using namespace std;
/*思路:要想平均等待时间最短,那就让接水时间短人的先接水
首先是将接水时间排序,由于输出数据要求排队顺序,
所以最好是用一个结构体储存排队打水人的序号和时间。*/

//定义一个结构体存储打水人的序号id和打水时间 
struct stu{
	int id;
	double t;  
}a[1005];

//sort的判断函数,a打水时间小于b打水时间,这样打水时间少的排在前面 
bool cmp(stu a, stu b){
	return a.t<b.t;
}

int main(){
	int n;
	scanf("%d",&n);//n个人排队打水 
	for(int i=1;i<=n;i++){
		scanf("%lf",&a[i].t);//打水时间 
		a[i].id = i;  //序号 
	}
	sort(a+1,a+n+1,cmp);//打水时间由少到多排序 
	double wt=0.0;//总的等待时间 
	for(int i=1;i<n;i++){
		wt+=(n-i)*a[i].t;//排队时,没有接到水的人都在等待 
		printf("%d ",a[i].id);
	} 
	printf("%d\n",a[n].id);
	printf("%.2lf",wt/n);
	return 0;
}