大家好,我是程序员吴师兄,明天就要上班,不知道大家焦不焦虑,反正我是不焦虑的,因为我又请了几天年假出去玩(逃
在等飞机的过程中,发现一道有趣的数学题,思考了半天居然做错了。。。
100个人回答五道题,有81人答对第一题,91人答对第二题,85人答对第三题,79人答对第四题,74人答对第五题。
答对三道题或三道题以上的人算及格,那么在这100人中至少有多少人及格呢?
先考虑如果只有AB两道题,100个人,第一反应是用集合的方式。
总共也就上面3种情况,其中第一种人数大于100非法,所以只存在后面2种情况。
可以得到如下结论:
看来已经找到了规律,那就按这个思路进一步扩大数据规模,考虑ABC三题。
再合成三题的关系。等等,好像有点复杂,这不是线性的复杂度,不好意思,小K的智商有点不够用,自闭了。
那小K是不是要准备放弃了呢,NO,never say give up。有时候不要撞倒南墙不回头,基于小K多年的经验,如果找到的规律不明显或者很复杂,一般都说明你走错了,所以这时要考虑切换思维方式。
只要错3道就不及格,一共有19+9+15+21+26=90道错题,那么90/3=30,则最多有30人不及格,所以最少有70人及格,perfect,收工。
Wait,总感觉有点怪怪的,倒不是因为太简单,而是对于信息量的直觉告诉我,这种解法忽略了很多的信息量。
只用了总数,而没有用到5道题的错题数量分布。那就直接告诉你总共错了90道就行了,为啥还要单独告诉具体的数量,这难道真的只是误导信息吗?
根据上面的解法,既然不关心具体分布,那就用极限思维,构造特殊数据。比如所有错题集中在A题。
总共还是错90道,但所有人都做对4题,应该是100人及格,再一次自闭。
小K:你说的很有道理,我竟无言以对。
先不跟你扯,咱们进一步思考,这个反例说明了一点:错题不能随意均摊,那就从这点下手。
如何将这些错题分配给最多的人。为了分析方便,先写一个简单的例子,如错题分布为7、8、9、10、11。
第一种分配:
到这里我们已经发现了规律,优先分配最大的3道会得到更多的人数。而在分配过程中最大的3道顺序会动态变化,这就启发了贪心的思想。
重复上面步骤,直到最后找不出3个不为0的数,也就是变为X,0,0,0,0或者X,Y,0,0,0。
转换问题:有5个矩形,顺序可随意。要切出宽度为3的N个矩形,要求总体叠加要尽量的高,最高有多少?
你品,你细品,这是不是同一个问题呀。所以要从最高的前3个开始一点一点的削它,哈哈。
回到原题,那到底至少有多少人呢?通过代码测试结果。
int main() {
int a[5], ans = 0;
for (int i = 0; i 5; ++i) {
cin >> a[i];
}
sort(a, a + 5, compare);
while (a[2] > 0) {
a[0]--;
a[1]--;
a[2]--;
sort(a, a + 5, compare);
ans++;
for (int i = 0; i 5; ++i) {
cout <" ";
}
cout }
cout <"ans="
return 0;
}