惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
J
Java Code Geeks
雷峰网
雷峰网
WordPress大学
WordPress大学
宝玉的分享
宝玉的分享
云风的 BLOG
云风的 BLOG
V
Visual Studio Blog
V
Vulnerabilities – Threatpost
S
Securelist
The Hacker News
The Hacker News
The Register - Security
The Register - Security
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Help Net Security
Help Net Security
G
Google Developers Blog
Hugging Face - Blog
Hugging Face - Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
M
MIT News - Artificial intelligence
AI
AI
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
The GitHub Blog
The GitHub Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Schneier on Security
Schneier on Security
N
Netflix TechBlog - Medium
T
The Blog of Author Tim Ferriss
Google DeepMind News
Google DeepMind News
Hacker News - Newest:
Hacker News - Newest: "LLM"
H
Hacker News: Front Page
博客园 - 司徒正美
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
B
Blog
Microsoft Azure Blog
Microsoft Azure Blog
大猫的无限游戏
大猫的无限游戏
Security Latest
Security Latest
Engineering at Meta
Engineering at Meta
N
News and Events Feed by Topic
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
酷 壳 – CoolShell
酷 壳 – CoolShell
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
T
Threat Research - Cisco Blogs
U
Unit 42
V
V2EX
V2EX - 技术
V2EX - 技术
L
LINUX DO - 最新话题
aimingoo的专栏
aimingoo的专栏
Microsoft Security Blog
Microsoft Security Blog
Recorded Future
Recorded Future
P
Privacy & Cybersecurity Law Blog
美团技术团队
小众软件
小众软件
F
Fortinet All Blogs

博客园 - quanben

TECLAST(台电)双系统板tPAD点评 酷比魔方WP10全奔点评 Git Commands Quick Notes Windows Commands and API Linux tricks 全本软件白名单 Quanben Software Whitelist 中文和英文的比较 特征向量到约当标准型 全本论现代中国学人 这才是人工智能的真正显著威胁之一 一些原理 Time-travel Models 哥德尔定理概述 全本一六年一月再论人工智能 如何保存微信的小视频 How to keep WeChat 'Sights' 葱类 Allium 全本论音乐三圣 an excellent capability of C# language and compiler 人类现代史的全本鱼难题
换啤酒问题
quanben · 2015-10-22 · via 博客园 - quanben

近日微信上有人传防痴呆问题:

2块钱买一瓶啤酒,四个瓶盖可以换一瓶啤酒,两个空瓶可以换一瓶啤酒,十块钱共能喝几瓶啤酒?

这个问题如果心算,如果就直肠子贪心法算的话,主要看记忆力。一般能心算出结果和零头的属于记忆力不错的,年轻人也不一定行。

如果在纸上算,只要不是太粗心的人,都能算出结果。但是学过一定数学的人,都怕这不是最优的结果。

其实假设单一解,贪心地算,这样一道题,结果很简单就是能喝15瓶酒,余下1个空瓶和三个瓶盖。但是如果我们列方程根据这些物品的价值来算,设啤酒价值为a,酒瓶价值为b,瓶盖价值为c,显然方程就是这样:

2¥ = a+b+c
2b = a+b+c
4c = a+b+c

很容易解出:

a = 0.5¥, b = 1¥, c = 0.5¥

这样,如果理想兑换的话(酒瓶和瓶盖能直接折算成钱/酒),10块钱能喝二十瓶啤酒,但这违反了题设的商业模式,显然无法做到。(但如果允许退款,是可以做到的,也是这道题目原题的答案)

貌似最优情况,也至少是要余下一个空瓶和一个瓶盖,但这也是不可能的。这个在数学结构上能够证明(从数学上应该能论证余b+2c和b+c是不可能的),也能用程序进行穷举证明,程序(穷举递归)如下:

  1 using System;
  2 
  3 namespace beers
  4 {
  5     class Program
  6     {
  7         class Asset
  8         {
  9             public Asset(int dollars)
 10             {
 11                 Dollars = dollars;
 12             }
 13 
 14             public Asset(Asset other)
 15             {
 16                 Beers = other.Beers;
 17                 Dollars = other.Dollars;
 18                 Bottles = other.Bottles;
 19                 Caps = other.Caps;
 20                 Record = other.Record;
 21             }
 22 
 23             public int Beers;
 24             public int Dollars;
 25             public int Bottles;
 26             public int Caps;
 27 
 28             // TODO string builder? it's just a tiny puzzle, don't worry about it
 29             public string Record;
 30 
 31             public bool ConsumeDollars()
 32             {
 33                 if (Dollars >= 2)
 34                 {
 35                     Dollars -= 2;
 36                     Beers++;
 37                     Bottles++;
 38                     Caps++;
 39                     Record += string.Format("use 2 dollars\n");
 40                     return true;
 41                 }
 42                 return false;
 43             }
 44 
 45             public bool ConsumeBottles()
 46             {
 47                 if (Bottles >= 2)
 48                 {
 49                     Bottles -= 2;
 50                     Beers++;
 51                     Bottles++;
 52                     Caps++;
 53                     Record += string.Format("use 2 bottles\n");
 54                     return true;
 55                 }
 56                 return false;
 57             }
 58 
 59             public bool ConsumeCaps()
 60             {
 61                 if (Caps >= 4)
 62                 {
 63                     Caps -= 4;
 64                     Beers++;
 65                     Bottles++;
 66                     Caps++;
 67                     Record += string.Format("use 4 caps\n");
 68                     return true;
 69                 }
 70                 return false;
 71             }
 72         }
 73 
 74         static Asset Solve(Asset input)
 75         {
 76             var o1 = new Asset(input);
 77             o1 = o1.ConsumeDollars() ? Solve(o1) : null;
 78 
 79             var o2 = new Asset(input);
 80             o2 = o2.ConsumeBottles() ? Solve(o2) : null;
 81 
 82             var o3 = new Asset(input);
 83             o3 = o3.ConsumeCaps() ? Solve(o3) : null;
 84 
 85             if (o1 != null && (o2 == null || o1.Beers > o2.Beers) && (o3 == null || o1.Beers > o3.Beers))
 86             {
 87                 return o1;
 88             }
 89 
 90             if (o2 != null && (o3 == null || o2.Beers > o3.Beers))
 91             {
 92                 return o2;
 93             }
 94 
 95             if (o3 != null)
 96             {
 97                 return o3;
 98             }
 99 
100             return input;
101         }
102 
103         static void Main(string[] args)
104         {
105             var ini = new Asset(10);
106             var opt = Solve(ini);
107             Console.WriteLine("result: {0} beers + {1} bottles {2} caps", opt.Beers, opt.Bottles, opt.Caps);
108             Console.WriteLine("process:\n{0}", opt.Record);
109         }
110     }
111 }