01
贪心算法是指在对问题求解时,总是做出在当前看来是好的选择。也就是说,不从整体优上加以考虑,只做出在某种意义上的局部优解。贪心算法不是对所有问题都能得到整体优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。
贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择。必须注意的是,贪心算法不是对所有问题都能得到整体优解,选择的贪心策略必须具备无后效性(即某个状态以后的过程不会影响以前的状态,只与当前状态有关。)
所以,对所采用的贪心策略一定要仔细分析其是否满足无后效性。
解题的一般步骤是:
1.建立数学模型来描述问题;
2.把求解的问题分成若干个子问题;
3.对每一子问题求解,得到子问题的局部优解;
4.把子问题的局部优解合成原来问题的一个解。
不能保证求得的后解是佳的
不能用来求大值或小值的问题
只能求满足某些约束条件的可行解的范围
贪心策略适用的前提是:局部优策略能导致产生全局优解。
实际上,贪心算法适用的情况很少。一般对一个问题分析是否适用于贪心算法,可以先选择该问题下的几个实际数据进行分析,就可以做出判断。
所谓贪心选择性质是指所求问题的整体优解可以通过一系列局部优的选择,换句话说,当考虑做何种选择的时候,我们只考虑对当前问题佳的选择而不考虑子问题的结果。这是贪心算法可行的个基本要素。贪心算法以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择终导致问题的整体优解。
当一个问题的优解包含其子问题的优解时,称此问题具有优子结构性质。问题的优子结构性质是该问题可用贪心算法求解的关键特征。
从问题的某一初始解出发:
while (朝给定总目标前进一步){利用可行的决策,求出可行解的一个解元素。}
由所有解元素组合成问题的一个可行解;



using namespace std; int N;struct Act {int start;int end; }act[100010];
bool cmp(Act a,Act b){ return a.end<b.end; }
int greedy_activity_selector(){ int num=1,i=1; for(int j=2;j<=N;j++) { if(act[j].start>=act[i].end) { i=j; num++; } } return num; }
int main(){ int t;scanf("%d",&t);while(t--) {scanf("%d",&N);for(int i=1;i<=N;i++) {scanf("%lld %lld",&act[i].start,&act[i].end); } act[].start=-1; act[].end=-1; sort(act+1,act+N+1,cmp);int res=greedy_activity_selector();cout<<res<<endl; } } #include<iostream>#include<algorithm>using namespace std;const int N=7;int Count[N]={3,,2,1,,3,5};int Value[N]={1,2,5,10,20,50,100};
int solve(int money){int num=;for(int i=N-1;i>=;i--) {int c=min(money/Value[i],Count[i]); money=money-c*Value[i]; num+=c; }if(money>) num=-1;return num; }
int main(){int money;cin>>money;int res=solve(money);if(res!=-1) cout<<res<<endl;else cout<<"NO"<<endl; } #include<iostream> using namespace std; const int N=4; void knapsack(float M,float v[],float w[],float x[]);
int main(){ float M=50;//背包所能容纳的重量 float w[]={0,10,30,20,5};//每种物品的重量 float v[]={0,200,400,100,10}; //每种物品的价值float x[N+1]={0}; //记录结果的数组 knapsack(M,v,w,x); cout<<"选择装下的物品比例:"<<endl; for(int i=1;i<=N;i++) cout<<"["<<i<<"]:"<<x[i]<<endl; }
void knapsack(float M,float v[],float w[],float x[]){ int i; //物品整件被装下 for(i=1;i<=N;i++) { if(w[i]>M) break; x[i]=1; M-=w[i]; } //物品部分被装下 if(i<=N) x[i]=M/w[i]; }
#include<iostream> #include<algorithm> using namespace std; int speed[10010]; int mintime[110];
bool cmp( const int &x,const int &y){ return x>y; }
int main(){ int n,m; memset(speed,,sizeof(speed)); memset(mintime,,sizeof(mintime)); cin>>n>>m; for(int i=;i<n;++i) cin>>speed[i]; sort(speed,speed+n,cmp); for(int i=;i<n;++i) { *min_element(mintime,mintime+m)+=speed[i]; } cout<<*max_element(mintime,mintime+m)<<endl; }#include<iostream>#include<algorithm>using namespace std;
int main(){int a[1000],t,n,sum;scanf("%d",&t);while(t--) {scanf("%d",&n); sum=0;for(int i=;i<n;i++) scanf("%d",&a[i]);while(n>3) { sum=min(sum+a[1]+a[0]+a[n-1]+a[1],sum+a[n-1]+a[0]+a[n-2]+a[0]); n-=2; }if(n==3) sum+=a[]+a[1]+a[2];else if(n==2) sum+=a[1];else sum+=a[];printf("%d\n",sum); } }
#include<cmath>#include<iostream>#include<algorithm>using namespace std;struct Point {double x;double y; }point[1000];
int cmp(const void *a, const void *b){return (*(Point *)a).x>(*(Point *)b).x?1:-1; }
int main(){int n,d;int num=1;while(cin>>n>>d) {int counting=1;if(n==&&d==) break;for(int i=;i<n;i++) {int x,y;cin>>x>>y;if(y>d) { counting=-1; }double t=sqrt(d*d-y*y);//转化为少区间的问题 point[i].x=x-t;//区间左端点 point[i].y=x+t;//区间右端点 }if(counting!=-1) { qsort(point,n,sizeof(point[]),cmp);//按区间左端点排序double s=point[].y;//区间右端点for(int i=1;i<n;i++) {if(point[i].x>s)//如果两个区间没有重合,增加雷达数目并更新右端点 { counting++; s=point[i].y; }else if(point[i].y<s)//如果第二个区间被完全包含于个区间,更新右端点 { s=point[i].y; } } }cout<<"Case "<<num<<':'<<' '<<counting<<endl; num++; } }#include<queue>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>using namespace std;long long int price[100010],t,n,res;
int main(){ ios::sync_with_stdio(false);cin>>t;while(t--) {cin>>n; priority_queue<long long int, vector<long long int>, greater<long long int> > q; res=0;for(int i=1;i<=n;i++) {cin>>price[i]; } res-=price[1]; res+=price[n];for(int i=2;i<=n-1;i=i+2) {long long int buy=min(price[i],price[i+1]);long long int sell=max(price[i],price[i+1]);if(!q.empty()) {if(buy>q.top()) { res=res-2*q.top()+buy+sell; q.pop(); q.push(buy); q.push(sell); }else { res=res-buy+sell; q.push(sell); } }else { res=res-buy+sell; q.push(sell); } } cout<<res<<endl; } }
#include<queue>#include<cstdio>#include<iostream>using namespace std;
int main(){long long int sum;int i,n,t,a,b;while(~scanf("%d",&n)) { priority_queue<int,vector<int>,greater<int> >q;for(i=;i<n;i++) {scanf("%d",&t); q.push(t); } sum=0;if(q.size()==1) { a=q.top(); sum+=a; q.pop(); }while(q.size()>1) { a=q.top(); q.pop(); b=q.top(); q.pop(); t=a+b; sum+=t; q.push(t); }printf("%lld\n",sum); } }
#include<iostream>#include<algorithm>#define INF 1000#define MAX_V 100using namespace std;
int main(){int V,E;int i,j,m,n;int cost[MAX_V][MAX_V];int d[MAX_V];bool used[MAX_V];cin>>V>>E; fill(d,d+V+1,INF); fill(used,used+V,false);for(i=;i<V;i++) {for(j=;j<V;j++) {if(i==j) cost[i][j]=0;else cost[i][j]=INF; } }for(m=;m<E;m++) {cin>>i>>j>>cost[i][j]; cost[j][i]=cost[i][j]; }cin>>n; d[n]=0;//源点while(true) {int v=V;for(m=;m<V;m++) { if((!used[m])&&(d[m]<d[v])) v=m; } if(v==V) break; used[v]=true;for(m=;m<V;m++) { d[m]=min(d[m],d[v]+cost[v][m]); } }for(i=;i<V;i++) {cout<<"the shortest distance between "<<n<<" and "<<i<<" is "<<d[i]<<endl; } }




#include<iostream>#include<algorithm>#define MAX_V 100#define INF 1000using namespace std;
int main(){int V,E;int i,j,m,n;int cost[MAX_V][MAX_V];int mincost[MAX_V];bool used[MAX_V];cin>>V>>E; fill(mincost,mincost+V+1,INF); fill(used,used+V,false);for(i=;i<V;i++) {for(j=;j<V;j++) {if(i==j) cost[i][j]=0;else cost[i][j]=INF; } }for(m=;m<E;m++) {cin>>i>>j>>cost[i][j]; cost[j][i]=cost[i][j]; } mincost[0]=0;int res=;while(true) {int v=V;for(m=;m<V;m++) { if((!used[m])&&(mincost[m]<mincost[v])) v=m; } if(v==V) break; used[v]=true; res+=mincost[v];for(m=;m<V;m++) { mincost[m]=min(mincost[m],cost[v][m]); } }cout<<res<<endl; }
#include<iostream>#include<algorithm>#define MAX_E 100using namespace std; struct edge {int u,v,cost; };int pre[MAX_E]; edge es[MAX_E];int find(int x);void initvalue(int x);bool same(int x,int y);void unite(int x,int y);bool comp(const edge& e1,const edge& e2);
int main(){int V,E;int i,j,m,n;cin>>V>>E; initvalue(V);for(i=;i<E;i++) cin>>es[i].u>>es[i].v>>es[i].cost; sort(es,es+E,comp);int res=;for(i=;i<E;i++) { edge e=es[i];if(!same(e.u,e.v)) { unite(e.u,e.v); res+=e.cost; } }cout<<res<<endl; }
bool comp(const edge& e1,const edge& e2){return e1.cost<e2.cost; }
void initvalue(int x){for(int i=;i<x;i++) pre[i]=i; }
int find(int x){int r=x;while(pre[r]!=r) r=pre[r];int i=x,j;while(pre[i]!=r) { j=pre[i]; pre[i]=r; i=j; }return r; }
bool same(int x,int y){if(find(x)==find(y)) return true;else return false; }
void unite(int x,int y){int fx=find(x);int fy=find(y);if(fx!=fy) pre[fx]=fy; }来源 :CSDN,简书等
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/615/viewspace-3163252/ ,如需转载,请注明出处,否则将追究法律责任。