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 } 
原文地址:https://www.cnblogs.com/qingoba/p/12511252.html