贪心问题2
T1:排队接水
排队接水这道题当之无愧是我错的最惨的一道题,由于答案的省略,我至今不知道源代码错在哪,甚至一度怀疑自己橙题都做不出来。后来改long long,改空格,重写了一遍才过。
查看代码
#include <bits/stdc++.h>
using namespace std;
int n;
struct STU
{
int t;
int num;
}a[1005];
bool cmp(STU a,STU b)
{
if(a.t<b.t) return true;
return false;
}
long long sum[1005],tot;
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i].t);
a[i].num=i+1;
}
sort(a,a+n,cmp);
printf("%d",a[0].num);
for(int i=1;i<n;i++)
{
sum[i]=sum[i-1]+a[i-1].t;
tot+=sum[i];
printf(" %d",a[i].num);
}
printf("\n%.2lf",tot*1.0/n*1.0);
return 0;
}
T2:最大积分
积分小的商品往前放,注意可能有一下进多级的情况
查看代码
#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
ull t[10010],sum,ans;
int n,m;
struct node
{
ull k,c;
bool operator<(const node &aa)const
{ return c<aa.c; }
}a[10010];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d%d",&a[i].k,&a[i].c);
scanf("%d",&m);
for(int i=1;i<=m;i++) scanf("%d",&t[i]);
t[m+1]=1e9;
sort(a+1,a+n+1);
int lev=1;
for(int i=1;i<=n;i++)
{
while(sum+a[i].k>=t[lev])
{
ans+=(t[lev]-sum)*a[i].c*lev;
a[i].k-=t[lev]-sum;
sum=t[lev];
lev++;
}
ans+=a[i].k*a[i].c*lev;
sum+=a[i].k;
}
printf("%d",ans);
return 0;
}
T3:砍树问题
由于树之间一定互不遮挡,所以砍完后不存在不相邻的树互相遮挡的情况,一定是两两之间比较
查看代码
#include<bits/stdc++.h>
using namespace std;
struct tree{ int id,h; }k[100010];
int n;
bool cmp(tree aa,tree bb) { return aa.id<bb.id; };
int main()
{
long long ans=0;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d%d",&k[i].id,&k[i].h);
sort(k+1,k+n+1,cmp);
for(int i=1;i<=n;i++)
{
if(i==1) ans+=max(0,k[i].h-(k[i+1].id-k[i].id));
else if(i==n) ans+=max(0,k[i].h-(k[i].id-k[i-1].id));
else ans+=max(0,max((k[i].h-(k[i].id-k[i-1].id)),(k[i].h-(k[i+1].id-k[i].id))));
}
printf("%d",ans);
return 0;
}
T4:出栈序列
应使大数先弹出。先预处理出后缀最大值,然后再栈上就只有两个操作:如果栈顶大于后缀最大值就输出,否则正常进栈
查看代码
#include<bits/stdc++.h>
using namespace std;
int n,maxn,top,a[1000010],last[1000010],st[1000010];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=n;i>0;i--)
{
maxn=max(maxn,a[i]);
last[i]=maxn;
}
for(int i=1;i<=n;i++)
{
st[++top]=a[i];
while(st[top]>last[i+1]) printf("%d ",st[top--]);
}
return 0;
}
T5:矩阵问题
一开始:这。。。跟贪心有关系?看完题解:妙啊
就是一旦有一行全黑了,那就完事了。那怎么构造一行全黑的呢?设该行为第 k 行,让第 k 列的黑色来染。那要是整个第 k 列一个黑色的都没有怎么办,那就先染一下第 k 列。所以说用 l [ i ] 预处理后,构造全黑行只需该行白子数(+1)的步数。接接下来枚举 k 即可。数据有两个不合法的。
查看代码
#include <bits/stdc++.h>
using namespace std;
int n,h[100010],l[100010];
char s[1010][1010];
int main()
{
int ans=-1;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",s[i]+1);
for(int j=1;j<=n;j++)
{
if(s[i][j]=='#')
{
h[i]++;
l[j]++;
ans=n;
}
}
}
if(ans==-1)
{
printf("-1");
return 0;
}
for(int i=1;i<=n;i++)
{
if(l[i]) ans=min(ans,n-h[i]);
else ans=min(ans,n-h[i]+1);
}
for(int i=1;i<=n;i++) if(l[i]!=n) ans++;
printf("%d",ans);
return 0;
}