「一本通」贪心
程序员文章站
2022-03-27 10:26:51
...
终于刷完了呼。。
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;
}
上一篇: 抄手是冷水下锅还是热水下锅