贪心算法(week 6)

P1199 [NOIP2010 普及组] 三国游戏 

看题可以得到:计算机的选人思路是选默契值最大的,所以只要小涵选择一个,与这一个相关默契值最大的肯定会被计算机选去,但由于默契值是相互的,所以与计算机所选的那个相关,默契值最大的那个被小涵选去了,所以只要让小涵每次选取默契值第二大的,再加上小涵选的第一个是不确定的,所以肯定存在小涵获胜的方案,而这个最大的默契值取每个武将与其他武将之间默契值的第二的最大值。

#include <iostream>
#include<algorithm>
using namespace std;
int main(){
	int n;cin>>n;
	int a[1005][1005];
	for(int i=1;i<n;i++){
		for(int j=i+1;j<=n;j++){
			cin>>a[i][j];
			a[j][i]=a[i][j];
		}
	}
	int max=0;
	for(int i=1;i<=n;i++){
		sort(a[i]+1,a[i]+n+1);
		if(a[i][n-1]>max)max=a[i][n-1];
	}
	cout<<"1"<<endl<<max;
    return 0;
}

P1007 独木桥 

  

想到方法之后题目并不难,因为士兵相遇时同时改变方向,在计算时间时就与士兵不相遇继续走是一样的,所以就是要看士兵离桥两边的长度。

需要注意的一个小细节就是:求最大和最小值的时候都是用更加大的值来替换,因为求最小的时候需要所有士兵都过河,而求最大的时候亦如此。

#include<iostream>
using namespace std;
int main(){
	int l;cin>>l;int n;cin>>n;
	int a_max[10005];int a_min[10005];
	int x;
	for(int i=1;i<=n;i++){
		cin>>x;
		a_max[i]=max(l-x+1,x);
		a_min[i]=min(l-x+1,x);
	}
	int max=a_max[1],min=a_min[1];
	for(int i=1;i<=n;i++){
		if(a_max[i]>max)max=a_max[i];
		if(a_min[i]>min)min=a_min[i];
	}
	cout<<min<<" "<<max;
    return 0;
}

P1223 排队接水 

排队接水和贪心算法中先让时间短的走、再走时间长的思路是一样的。所有这个题就只需要对原有数组从小到大进行排序,然后再比较两个数组得到数组的下标号输出,(每一段 × 等了这一段的人数)求和得到总时间。

#include <iostream>
#include<algorithm>
using namespace std;
int main(){
	double sum=0;
	bool w[1005]={0};
	int a[1005];
	int n;cin>>n;
	for(int i=0;i<n;i++){
		cin>>a[i];
	}
	int b[1005],c[1005];
	for(int i=0;i<n;i++){
		b[i]=a[i];
	}
	sort(b,b+n);
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			if(!w[j]&&b[i]==a[j]){
				c[i]=j+1;
				w[j]=true;
				break;
			}
		}
	}
	for(int i=0;i<n;i++){
		cout<<c[i]<<" ";
	}
	cout<<endl;
	for(int i=0;i<n;i++){
		sum+=(n-i-1)*b[i];
	}
	printf("%.2f",sum/n);
    return 0;
}

P1090 [NOIP2004 提高组] 合并果子 / [USACO06NOV] Fence Repair G

使用优先队列的方法,使队列一直从大到小排列,取出最小的两个加到总和里面再把这两个的和放到队列中,直到队列中元素数只有一个的时候结束。

STL:
栈和队列:
头文件:#include<stack>  //栈
              #include<queue>//队列
定义:stack<int> s;  //栈
          queue<int> q;//队列
基本语句:
栈:s.empty( )//栈空返回true
       s.size( )//返回元素个数
       s.pop( )//删去栈顶元素
       s.top( )//返回栈顶元素
       s.push(x)//让x入栈
队列:q.empty( )//队列为空返回true
          q.size( )//返回元素个数
          q.pop( )//删除队首元素
          q.front( )//返回队首元素
          q.back( )//返回队尾元素
          q.push(x)//让x入队
优先队列:
与队列相似但是优先级最高的先出队
//升序队列
priority_queue <int,vector<int>,greater<int> > q;
//降序队列
priority_queue <int,vector<int>,less<int> >q;

stl中队首元素队列用front优先队列用top
 

#include<iostream>
#include<queue>
using namespace std;
int main(){
	priority_queue<int,vector<int>,greater<int>>q;
	int n;cin>>n;
	for(int i=0;i<n;i++){
		int x;cin>>x;
		q.push(x);
	}
	int sum=0;
	while(q.size()>1){
		int ans=0;
		ans+=q.top();
		q.pop();
		ans+=q.top();
		q.pop();
		sum+=ans;
		q.push(ans);
	}
	cout<<sum;
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值