一.贪心算法
考虑当前状态下局部最优(或较优)的策略;
二.题目
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 ;
}