《算法笔记》4.4贪心

一.贪心算法
考虑当前状态下局部最优(或较优)的策略;

二.题目
1.PAT B1020
注意:
1).排名直接体现在数组下标中,无需储存在结构体中;

代码:

#include<cstdio>
#include<algorithm>
using namespace std ;
struct mooncake {
	double store ;
	double sell ;
	double price ;
}cake[1010] ;
bool cmp(mooncake a , mooncake b) {
	return a.price > b.price ;
}
int main() {
	int N , D ;
	scanf("%d%d",&N,&D) ;
	for(int i = 0 ; i < N ; i ++) scanf("%lf",&cake[i].store) ;
	for(int i = 0 ; i < N ; i ++) {
		scanf("%lf",&cake[i].sell) ; 
		cake[i].price = cake[i].sell / cake[i].store ;
	}
	sort(cake , cake + N , cmp) ;
	double ans = 0 ;
	for(int i = 0 ; i < N ; i ++) {
		if(D > cake[i].store) {
			ans += cake[i].sell ;
			D -= cake[i].store ;
		}
		else {
			ans += cake[i].price * D ;
			break ;
		}
	}
	printf("%.2lf",ans) ;
	return 0 ;
} 

2.PAT B1023
注意:
1).可以不用输出整数而是依次输出每个数;

代码:

#include<cstdio>
using namespace std ;
int main() {
	int n[10] ;
	int sum = 0 ;
	for(int i = 0 ; i < 10 ; i ++) {
		scanf("%d",&n[i]) ;
		sum += n[i] ;
	}
	for(int i = 0 ; i < sum ; i ++) {
		for(int j = 0 ; j < 10 ; j ++) {
			if(i == 0) {
				if(n[j] > 0 && j != 0) {
					printf("%d",j) ;
					n[j] -- ;
					break ;
				}
			}
			else {
				if(n[j] > 0 ) {
					printf("%d",j) ;
					n[j] -- ;
					break ;
				}
			}
		}
	}
	return 0 ;
}

3.区间不相交问题(区间选点问题)
思路:
将两两相交的一堆区间(这堆区间只能选出一个区间)分为两类:第一类是包含关系,选被包含的;第二类是非包含关系,按左端点从大到小排,选左端点最大的;
在这里插入图片描述
所以按照左端点从大到小排序,左端点相等则按照右端点从小到大排序,这样能划分出几个两两相交的区间堆,选出的是每堆的第一个(规则为:包含最小,不包含左最大);

代码:

#include<cstdio>
#include<algorithm>
using namespace std ;
struct Inteval {
	int left , right ;
}I[1010];
bool cmp(Inteval a , Inteval b) {
	if(a.left != b.left) return a.left > b.left ;
	else return a.right < b.right ;
}
int main() {
	int n ;
	scanf("%d",&n) ;
	for(int i = 0 ; i < n ; i ++) scanf("%d%d",&I[i].left,&I[i].right) ;
	sort(I , I + n , cmp) ;
	int ans = 1 ;
	int last_left = I[0].left ;
	for(int i = 1 ; i < n ; i ++) {
		if(I[i].right <= last_left) {
			last_left = I[i].left ;
			ans ++ ;
		}
	}
	printf("%d",ans) ;
	return 0 ;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值