B-咕咕东想吃饭(贪心算法)

B-咕咕东想吃饭(贪心算法)

一、题目描述

咕咕东考试周开始了,考试周一共有n天。他不想考试周这么累,于是打算每天都吃顿好的。他决定每天都吃生煎,咕咕东每天需要买aia_iai​个生煎。但是生煎店为了刺激消费,只有两种购买方式:
①在某一天一次性买两个生煎。
②今天买一个生煎,同时为明天买一个生煎,店家会给一个券,第二天用券来拿。
没有其余的购买方式,这两种购买方式可以用无数次,但是咕咕东是个节俭的好孩子,他训练结束就走了,不允许训练结束时手里有券。咕咕东非常有钱,你不需要担心咕咕东没钱,但是咕咕东太笨了,他想问你他能否在考试周每天都能恰好买aia_iai​个生煎。

输入格式

输入两行,第一行输入一个正整数n(1<=n<=100000)(1<=n<=100000)(1<=n<=100000),表示考试周的天数。
第二行有n个数,第i个数ai(0<=ai<=10000)a_i(0<=a_i<=10000)ai​(0<=ai​<=10000)表示第i天咕咕东要买的生煎的数量。

输出格式

如果可以满足咕咕东奇怪的要求,输出"YES",如果不能满足,输出“NO”。(输出不带引号)

样例输入1

4
1 2 1 2

样例输出1

YES

样例输入2

3
1 0 1

样例输出2

NO

数据规模

数据点 	n(上限) 	aia_iai​(上限)
1,2 	10 	10
3,4,5 	1000 	10
6,7 	10 	10000
8,9,10 	100000 	10000

二、思路与算法

选用贪心算法,想要每天吃到一定数量的生煎,那么某天如果要吃偶数个生煎,就全选方案1,奇数个,选方案二,原因是什么呢?
因为本题目的是考察某种安排是否能够实现,并不需要求最优解或者其他。
同时,安排是否能实现,只与每天生煎数的奇偶有关,若想让一个奇数变偶,1足够了,2、4、6等偶数反而没用,3、5、7等奇数和1效果是一样的(如果1不行,3、5、7等也不行)。
所以,出现了上述贪心策略,而不需要去遍历所有可能性(这样的dfs相当于根本没有剪枝)。

三、代码实现

一开始在csp模考中,我想的算法是dfs搜索(以前都没有根据数据判断算法可不可用的意识),结果显然超时,所以这个代码不一定对,因为只是前几个点ac,后面可能有错误没机会报出来。

//dfs方法 数据太多 会超时 
#include<iostream>
#include<vector>
using namespace std; 

int n=0;
vector<int> a(0);
int flag=0;
 
void solution(int i,int num){
	if(i>n-1||num<0){return;}
	if(i==n-1){
		if(num%2==1){return;}
		else{flag=1;	return;}
	}
	else{
		int n=num/2;
		for(int k=0;k<=n;k++){
			solution(i+1,a[i+1]-(num-2*k));
		}
	}
	return;
}

int main(){
	scanf("%d",&n); 
	int temp=0;
	for(int i=0;i<n;i++){
		scanf("%d",&temp);
		a.push_back(temp);
	}
	solution(0,a[0]);
	if(flag==1){cout<<"YES\n";}
	else{cout<<"NO\n";}
	return 0;
}

之后一直超时,询问学长才知道,一看这个数据规模就应该排除搜索…
所以本题选用的是贪心算法。

#include <cstdio>
//贪心算法 
int main(){
	int n=0,temp=0,flag=0;//标记此时是否有券 
	scanf("%d",&n);
	int a[n];
	for(int i=0;i<n;i++){
		scanf("%d",&a[i]);
	}
	for(int i=0;i<n;i++){
		if(a[i]%2==0){
			if(flag==0){continue;}
			else{flag=1;	continue;}
		}
		else{
			if(flag==0){flag=1;		continue;}
			else{flag=0;	continue;}
		}
	}
	if(flag==1){printf("NO\n");}
	else{printf("YES\n");}
	return 0;
}

四、经验与总结

  1. 一定一定!!想算法前要先看数据规模!数据规模很大的,绝对不要想n^2及以上时间复杂度的算法!dfs、bfs不进行记忆性剪枝,更不要想!
  2. 看待问题一定要更深层次!不能看完表面,就想算法,就开始实现。算法最根本,算法如果错了,后续所有实现都是在做无用功。
  3. 再次提醒:输入输出用scanf和printf!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值