关于贪心题型的总结(没写完)

排座椅:
用到了排序的贪心,由于数量不知道多少,所以先找排完序最优的,可得最优解(一定关注题面上是否有最字) #include
<bits/stdc++.h> using namespace std; inline int read(){ int num=0,f=1; char c=getchar(); while(!isdigit(c)){if(c=='-') f=-1; c=getchar();} while(isdigit(c)){num=(num<<1)+(num<<3)+(c^48); c=getchar();} return num*f; } const int maxn=2010; //cautious:to avoid making mistakes please be careful to the range of the data int m,n,k,l,d,aj[maxn],bj[maxn],a[maxn],b[maxn]; bool jud1[maxn],jud2[maxn]; inline int in(){ m=read(); n=read(); k=read(); l=read(); d=read(); for(int i=1;i<=d;i++){ int x1,y1,x2,y2; y1=read(); x1=read(); y2=read(); x2=read(); if(x1==x2) aj[min(y1,y2)]++; if(y1==y2) bj[min(x1,x2)]++; } } inline int test2(){ for(int i=1;i<=2010;i++) for(int j=1;j<=bj[i];j++) if(bj[i]) cout<<i<<" "<<bj[i]<<endl; } //cautious(important):do not try to sort the bucket it will make it valueless inline int work(){ int maxx,cnt=0,ans=0,num; for(int i=1;i<=k;i++){ maxx=0; for(int j=1;j<=2010;j++){ if(aj[j]>maxx and jud1[j]==0){ //cautious:after the change the jud[j] is changed to the jud[num] without observing that leads to a big mistake maxx=aj[j]; num=j; } } jud1[num]=1; cnt++; a[cnt]=num; } sort(a+1,a+k+1); for(int i=1;i<=l;i++){ maxx=0; for(int j=1;j<=2010;j++){ if(bj[j]>maxx and jud2[j]==0){ //cout<<"maxx:"<<maxx<<" "<<"j:"<<j<<" "<<"bj[j]:"<<bj[j]<<endl; maxx=bj[j]; num=j; } } jud2[num]=1; ans++; b[ans]=num; } //for(int i=1;i<=l;i++) cout<<b[i]<<" "; sort(b+1,b+l+1); } inline int test1(){ for(int i=1;i<=k;i++) cout<<a[i]<<" "; cout<<endl; for(int i=1;i<=l;i++) cout<<b[i]<<" "; } inline int out(){ for(int i=1;i<=k;i++){ if(i!=k) cout<<a[i]<<" "; else cout<<a[i]<<endl; } for(int i=1;i<=l;i++){ if(i!=l) cout<<b[i]<<" "; else cout<<b[i]; } } //cautious:there are no any blanks when i==k int main(){ freopen("seats.in","r",stdin); freopen("seats.out","w",stdout); in(); work(); out(); //test1(); //test2(); }


均分制牌:
本题用到了等效的方法:对于样的有限制的左右两侧传递模型,可以考虑单一方向的传递并考虑负数(很重要的一种思路)

#include <bits/stdc++.h>
using namespace std;
const int maxn=10010;
int n,sum,a[maxn],ans;
inline int read(){
int num=0,f=1; char c=getchar();
while(!isdigit(c)){if(c=='-') f=-1; c=getchar();}
while(isdigit(c)){num=(num<<1)+(num<<3)+(c^48); c=getchar();}
return num*f;
}
inline int in(){
n=read();
for(int i=1;i<=n;i++){
a[i]=read(); sum+=a[i];
}
sum/=n;
}
inline int work(){
for(int i=1;i<=n;i++){
int cnt=a[i]-sum;
if(cnt==0) continue;
else{
a[i+1]=a[i+1]+cnt;
ans++;
}
}
}
inline int out(){
cout<<ans;
}
int main(){
in();
work();
out();
}

 

posted @ 2018-07-16 21:50  TimDucan  阅读(123)  评论(0编辑  收藏  举报