贪心问题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;
}

 

posted @ 2022-02-18 08:52  fervency  阅读(21)  评论(0编辑  收藏  举报