Week4 CSP-M1 B - 咕咕东想吃饭
题目描述:
咕咕东考试周开始了,考试周一共有n天。他不想考试周这么累,于是打算每天都吃顿好的。他决定每天都吃生煎,咕咕东每天需要买ai个生煎。但是生煎店为了刺激消费,只有两种购买方式:①在某一天一次性买两个生煎 ②今天买一个生煎,同时为明天买一个生煎,店家会给一个券,第二天用券来拿。
没有其余的购买方式,这两种购买方式可以用无数次,但是咕咕东是个节俭的好孩子,他考试结束就走了,不允许考试结束时手里有券。咕咕东非常有钱,你不需要担心咕咕东没钱,但是咕咕东太笨了,他想问你他能否在考试周每天都能恰好买ai个生煎。
需要补充的题意:只要手里有昨天买的券,今天就必须用,否则就是失败;最后一天,不能再用第二种方式买生煎。
思路:
①要买就买一个券,买多个券没有必要
②第i天,当ai是奇数时,如果需要买券,只需要买1个券;如果有券,就不买券
③第i天,当ai是偶数时,如果有券,就再买一个券,如果没券,就不买券
思路正确性分析:
为什么以上思路是正确的?即为何没有必要买多个券?
假设我买了m个券,m>=2,则m=2k+1或m=2k;
当m=2k时,第二天完全可以用k次买两个生煎,而不必要在今天冒险买券
当m=2k+1时,只有1个券是必须买的,剩下2k个券,第二天完全可以用k次买两个生煎,而不必要在今天冒险买券
总结:
还是那句话,先对问题进行,抽象,分析,再做;好像有一点贪心的感觉
上述证明好像是利用了“贪心得到的结果不会比最优解差”
代码:
1 #include <cstdio> 2 #include <iostream> 3 using namespace std; 4 int main() 5 { 6 int last=0; //最开始没券 7 int n; cin>>n; 8 for(int i=1;i<=n;i++) 9 { 10 int t; scanf("%d",&t); 11 if(t&1) //要买奇数个生煎 12 { 13 if(last==1) last=0; 14 else if(last==0) last=1; 15 } 16 else if(t==0&&last==1) //要买零个生煎 17 { 18 cout<<"NO"<<endl; 19 return 0; 20 } 21 else if(last==1) last=1; //要买偶数个生煎 22 } 23 if(last==1) cout<<"NO"<<endl; 24 else cout<<"YES"<<endl; 25 return 0; 26 }