「一本通」贪心

终于刷完了呼。。


1.1.6 糖果传递 数论+贪心
有 n 个小朋友坐成一圈,每人有 ai 颗糖果。每人只能给左右两人传递糖果。每人每次传递一颗糖果的代价为1。求使所有人获得均等糖果的最小代价。

别人题解的截图,出处找不到了233
//不知是哪位巨佬最初写的题解,大家都是这一篇转来转去(侵删侵删
没加读优的程序

#include<bits/stdc++.h>
using namespace std;
long long n,ed,a[1000005],c[1000005],ans=0;
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i]; ed+=a[i];
    }
    ed/=n;
    for(int i=1;i<=n;i++) c[i]=c[i-1]+a[i]-ed;
    sort(c+1,c+n+1);
    long long cmp=c[n/2];
    for(int i=1;i<=n;i++) ans+=abs(cmp-c[i]);
    printf("%lld\n",ans);
    return 0;
}

1.1.3 喷水装置 预处理+贪心
长 L 米,宽 W 米的草坪里装有 n 个浇灌喷头。每个喷头都装在草坪中心线上(离两边各 W/2 米)。我们知道每个喷头的位置(离草坪中心线左端的距离),以及它能覆盖到的浇灌范围。
请问:如果要同时浇灌整块草坪,最少需要打开多少个喷头?
这里写图片描述
圆形不方便处理,我们转换成长方形表示每个喷头能完全覆盖到的范围
这里写图片描述
真正完全覆盖的长度是红线表示的距离。(勾股求)
其余细节见代码注释

#include<bits/stdc++.h>
using namespace std;
int t,n,len,ans;
double w;
struct node{double x,y;}a[15005];
int cmp(node x1,node x2){return x1.x<x2.x;}
int read(){
    int x=0,f=1; char c; c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
    return x*f;
}

int main(){
    t=read();
    while(t--){
        ans=0;n=read();len=read();cin>>w; w/=2.0; int tot=0;
        for(int i=1;i<=n;i++){
            int s=read(); double r=read();
            if(r<w) continue; //草坪宽都覆盖不了的直接舍去
            r=sqrt(r*r-w*w); //见上图
            a[++tot].x=s-r; a[tot].y=s+r;//覆盖的左右边界
        }
        sort(a+1,a+tot+1,cmp); //按左边界排序,方便处理
        double k=0; int i=1; //k是当前最右边界
        if(a[1].x>0) {printf("-1\n"); continue;}
        while(i<=tot){
            double maxx=-1.0;
            while(a[i].x<=k&&i<=tot) {maxx=max(maxx,a[i].y);i++;}
            if(maxx>k){
                k=maxx; ans++; //k更新
                if(k>=len) break;
            }else break; //已经到了最优,直接退
        }
        if(k<len) printf("-1\n");
        else printf("%d\n",ans);
    }
    return 0;
}

1.1.5 钓鱼 贪心+递推
这里写图片描述

#include<bits/stdc++.h>
using namespace std;
int n,h,x,ans;
int a[101],t[101][250],f[101][250];
int read(){
    int x=0,f=1; char c; c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
    return x*f;
}

int main(){
    n=read(); h=read(); h*=12;
    for(int i=1;i<=n;i++) a[i]=read();
    for(int i=1;i<=n;i++){
        x=read();
        for(int j=1;j<=h;j++) 
         t[i][j]=t[i][j-1]+a[i],a[i]=max(0,a[i]-x);
    }
    a[1]=0;
    for(int i=2;i<=n;i++) a[i]=read();
    for(int i=1;i<=n;a[i]+=a[i-1],i++)
     for(int j=1;j<=h;j++)
      for(int k=a[i-1];k<=j-a[i];k++){
        f[i][j]=max(f[i-1][k]+t[i][j-k-a[i]],f[i][j]);
        ans=max(ans,f[i][j]);
      }
    printf("%d",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/MiaoZ_/article/details/81559074