在对问题求解时,总是作出在当前看来是最好的选择。也就是说,不从整体上加以考虑,它所作出的仅仅是在某种意义上的局部最优解(是否是全局最优,需要证明)。
若要用贪心算法求解某问题的整体最优解,必须首先证明贪心思想在该问题的应用结果就是最优解!!
1、从问题的某个初始解出发。
2、采用循环语句,当可以向求解目标前进一步时,就根据局部最优策略,得到一个部分解,缩小问题的范围或规模。
3、将所有部分解综合起来,得到问题的最终解。
hdoj1050
只需要找出最大相交数即可
#include<iostream>
#include<vector>
#include<map>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
const int N = 1000;
int main(){
int a[N] = {0};
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
int m, mx1 = 0;
scanf("%d",&m);
for(int j=0;j<m;j++){
int c, d;
scanf("%d%d",&c,&d);
c-=1;
c/=2;
d-=1;
d/=2;
if(c>d) swap(c, d);
if(d>mx1) mx1 = d;
for(int p=c;p<=d;p++){
a[p]++;
}}
int mx2 = 0;
for(int j=0;j<=mx1;j++){
if(a[j]>mx2) mx2 = a[j];
a[j] = 0;
}
printf("%d\n",mx2*10);
}
return 0;
}
hdoj1789
先对日期从小到大排序,如果日期相同,则扣分多的排在前面。如果相同日期内有扣分多的,则就用前面做扣分少的作业的时间来做这门作业;如果没有比他小的,就扣这门作业的分。
#include<iostream>
#include<vector>
#include<map>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
const int N = 1005;
struct node{
int s, t;
bool f;
}work[N];
int cmp(node a, node b){
if(a.t!=b.t) return a.t<b.t;
return a.s>b.s;
}
int main(){
int a[N] = {0};
int n;
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&work[i].t);
work[i].f = true;
}
for(int i=0;i<n;i++)
scanf("%d",&work[i].s);
sort(work,work+n,cmp);
int ans = 0;
int k = 1;
for(int i=0;i<n;i++){
if(work[i].t>=k){
k++;
continue;
}
int p = work[i].s;
int pos = i;
for(int j = 0;j<i;j++){
if(p>work[j].s&&work[j].f){
p = work[j].s;
pos = j;
}
}
ans+=p;
work[pos].f = false;
}
printf("%d\n",ans);
}
return 0;
}
hdoj2037
按结束时间牌序。
证明:会不会有比这更个局部的,思考一下发现没有
#include<iostream>
#include<vector>
#include<map>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
const int N = 105;
struct node{
int s, t;
}a[N];
int cmp(node e, node f){
return e.t<f.t;
}
int main(){
int n;
while(scanf("%d",&n)&&n!=0){
for(int i = 0;i<n;i++){
scanf("%d%d",&a[i].s,&a[i].t);
}
sort(a,a+n,cmp);
int ans = 0;
int pos = 0;
for(int i=0;i<n;i++){
if(i==0) ans++;
else{
if(a[i].s>=a[pos].t){
ans++;
pos = i;}
}
}
printf("%d\n",ans);
}
return 0;
}
hdoj2454
可图性判定!
1、度序列:若把图G所有顶点的度数排成一个序列S,则称S为图G的度序列。
2、序列是可图的:一个非负整数组成的有限序列如果是某个无向图的度序列,则称该序列是可图的。
Havel-Hakimi定理很容易理解:
三步走就可以了:
第一步:把序列按降序排序。
第二步:删除第一个数x。
第三步:从头开始,数x个数,全部-1
不断重复上述过程直到序列出现负数=不可图,全都为0=可图
#include<iostream>
#include<vector>
#include<map>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
const int N = 1005;
int cmp(int e, int f){
return e>f;
}
void fun(int* a, int n){
for(int i=0;i<n;i++){
a[i] = a[i+1];
}
}
int main(){
int T;
int a[N] = {0};
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
bool f = true;
do{
sort(a, a+n, cmp);
int t = a[0];
fun(a, n);
n--;
for(int i=0;i<t;i++){
a[i]--;
}
for(int i=0;i<n;i++){
if(a[i]<0){ f = false;
break;}
}
}while(n!=0);
if(f) printf("yes\n");
else printf("no\n");
}
return 0;
}
hdoj1052
先用最快马比 不行再用最慢马比 都不行 就送最慢马给忘得最快马
#include<iostream>
#include<vector>
#include<map>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
const int N = 1005;
int cmp(int e, int f){
return e>f;
}
int main(){
int n;
while(scanf("%d",&n)&&n!=0){
int s1 = 0, s2 = 0, f1 = n-1, f2 = n-1;
int a[N] = {0}, b[N] = {0};
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
for(int i=0;i<n;i++)
scanf("%d",&b[i]);
sort(a,a+n,cmp);
sort(b,b+n,cmp);
int ans = 0;
while(n--){
if(a[s1]>b[s2]){
s1++;
s2++;
ans+=200;
}
else if(a[f1]>b[f2]){
f1--;
f2--;
ans+=200;
}
else if(a[f1]==b[s2]){
s2++, f1--;
}
else{
s2++, f1--;
ans-=200;
}
}
printf("%d\n",ans);
}
return 0;
}
sort总结:
头文件:#include
sort(首地址, 尾地址+1, [cmp函数])
第三个参数不写,默认递增
一个综合示范:
bool cmp1(student x, student y)
{ if( fabs(x.score - y.score) > 0.00001 )
return x.score > y.score;
if(x.age != y.age) return x.age < y.age;
return strcmp(x.name,y.name) < 0 ;
}