问题描述
咕咕东考试周开始了,考试周一共有n天。他不想考试周这么累,于是打算每天都吃顿好的。他决定每天都吃生煎,咕咕东每天需要买aia_ia i 个生煎。但是生煎店为了刺激消费,只有两种购买方式:①在某一天一次性买两个生煎。②今天买一个生煎,同时为明天买一个生煎,店家会给一个券,第二天用券来拿。没有其余的购买方式,这两种购买方式可以用无数次,但是咕咕东是个节俭的好孩子,他训练结束就走了,不允许训练结束时手里有券。咕咕东非常有钱,你不需要担心咕咕东没钱,但是咕咕东太笨了,他想问你他能否在考试周每天都能恰好买aia_ia 个生煎。
Input
输入两行,第一行输入一个正整数n(1<=n<=100000),表示考试周的天数,第二行有n个数,第i个数ai(0<=ai<=10000)表示第i天咕咕东要买的生煎的数量。
Output
如果可以满足咕咕东奇怪的要求,输出"YES",如果不能满足,输出“NO”。(输出不带引号)
Sample input1
4
1 2 1 2
1
2
Sample output1
YES
1
Sample input2
3
1 0 1
1
2
Sample output2
NO
1
解题思路
因为只有两种策略,买两个或者买一个加上明天的一张券,即使次数不限,我们仍然可以将其转化为0,1,2这样一个简单化后的问题。之后根据第一天的情况递推地得到后一天的情况,直到有不符合条件的情况出现。
#include<iostream> using namespace std; /*每天 ai 个 购买 一次两个;一个+一个明天的quan */ //从最后来判断 3=1+2 2---一次买来的 错误1--前一天买了1+1券 // 前一天 1+1 (当作做后一天处理)2---- 2 or 1+1 1-- 1+1 // ==1 再前一天为方案1 再前一天当作最后一天 // ==2 再前一天为方案2 再前一天当作前一天 int main(){ int n ; while(cin>>n){ //cin>>n; int *ar=new int[n]; int *plan= new int[n]; bool can=true; for(int i=0;i<n;i++) plan[i]=0;//0 没买 ;1 1+1 ; 2 2 for(int i=0;i<n;i++) { cin>>ar[i]; while(ar[i]>3) ar[i]-=2; } if(ar[0]==3) ar[0]=1; plan[0]=ar[0]; for(int i=1;i<n-1;i++){ //0 1 2 3 if(plan[i-1]==0||plan[i-1]==2){ if(ar[i]==3||ar[i]==1) { plan[i]=1; } else plan[i]=ar[i]; } else if(plan[i-1]==1){ if(ar[i]==0) { can=false; break; } else plan[i]=ar[i]-1; } } if(can){ if(plan[n-2]==0||plan[n-2]==2) { if(ar[n-1]!=2 && ar[n-1]!=0) { can=false; } //else plan[n-1]=2; } if(plan[n-2]==1){ if(ar[n-1]!=3 && ar[n-1]!=1) can = false; } //else plan[n-1]= } // for(int i=0;i<n-1;i++) // cout<<plan[i]<<" "; // cout<<2<<endl; if(can) { cout<<"YES"<<endl; } else cout<<"NO"<<endl; } return 0; } /* 1 3 3 2 1 1+1 1+2 2+1 1+1 1+0 YES 1 3 2 1 2 1+1 1+2 2 1+1 1+1?错误 1 3 2 2 2 1 3 2 1 1 1 1 4 3 5 9 8 1+1 1+2+1 1+2 4+1 1+8 8 */