Problem 2118 分蛋糕 FZU【博弈】

3 篇文章 0 订阅

这题其实特别坑,五分钟想出公式

1-1/2+1/3-1/4……1/n

尝试各种姿势解这个值(总觉得是一个有极值的函数(虽然事实是确实是有的)),各种精度近似值 感觉快要疯了……

两小时后,通过百度发现上面那个公式果然是有极值 的,ln2

通过各种简单高数就能推导出来。。 = = 、嗯  已经完全还给老师的高数

代码就不贴了,题目见下……至于是怎么推出那个公式的。。。嗯  就是靠感觉……据说可以通过假设到第N块蛋糕的时候,其中一人不得不接受另一个人的方案为契机,科学地推导出上述公式……

 Problem 2118 分蛋糕

Accept: 48    Submit: 414
Time Limit: 1000 mSec    Memory Limit : 32768 KB

 Problem Description

小明和小方是双胞胎兄弟。这天他们的妈妈给他们买了一块大蛋糕。他们为了分蛋糕问题争执不休。于是,他们就商量了一个分蛋糕的方案分蛋糕。规则是这样的,小明比较大,由小明先提出分蛋糕的方案,小方可以选择接受或者否决。如果小方接受,就按照小明提出的方案分;如果他否决,就由小方提方案,小明来选择是否接受。这个过程轮流进行,直到有人提出的方案被接受为止。但不幸的是,他们妈妈买的这块蛋糕会融化,第n个阶段这块蛋糕就只剩下1/n 。即如果一开始的方案被接受,他们两个分到的蛋糕总和是1块蛋糕,如果第二次方案才被接受,他们两个分到的蛋糕总和就只有0.5块蛋糕。以此类推。小明和小方都是聪明人,而且他们都只关心自己是不是能分到足够大的蛋糕,并不刻意害人。

假设蛋糕只有一次分的机会,如果小方不接受就谁也得不到。那么结果是小明提出要整块蛋糕,小方也会接受。而该题中的蛋糕是只会不断融化,并不会消失,因此他们可以进行无限轮次的谈判,直到有人的方案被接受。

 Input

有多组测试数据,首先输入case数N(case数至多100),处理到文件尾。然后是N行。每一行一个整数M(1<=M<=1000),代表蛋糕的质量。

 Output

对于例子,输出一行,表示小明分了多少蛋糕,小方分了多少蛋糕。中间空格隔开。结果保留到小数点后6位。

 Sample Input

15

 Sample Output

2.500000 2.500000(该输出示例并不是正确答案,只是做出格式示范)

 Source

FOJ有奖月赛-2013年4月(校赛热身赛)

另外在NYOJ上发现了一题 1/n*n的题目

分蛋糕

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 4
描述

      小明和小方是双胞胎兄弟。这天他们的妈妈给他们买了一块大蛋糕,他们为了分蛋糕问题争执不休。于是,他们就商量了一个分蛋糕的方案分蛋糕。规则是这样的:小明比较大,由小明先提出分蛋糕的方案,小方可以选择接受或者否决,如果小方接受,就按照小明提出的方案分;如果他否决,就由小方提方案,小明来选择是否接受。这个过程轮流进行,直到有人提出的方案被接受为止。但不幸的是,他们妈妈买的这块蛋糕会融化,第n个阶段这块蛋糕就只剩下1/n2 。即如果一开始的方案被接受,他们两个分到的蛋糕总和是一整块儿蛋糕,如果第二次方案才被接受,他们两个分到的蛋糕总和就只有1/4块蛋糕,以此类推。小明和小方都是聪明人,而且他们都只关心自己是不是能分到足够大的蛋糕,并不刻意害人。

假设蛋糕只有一次分的机会,如果小方不接受就谁也得不到。那么结果是小明提出要整块蛋糕,小方也会接受。而该题中的蛋糕是只会不断融化,并不会消失,因此他们可以进行无限轮次的谈判,直到有人的方案被接受。

输入
有多组测试数据,首先输入case数N(case数至多100),处理到文件尾。然后是N行。每一行一个整数M(1<=M<=100000),代表蛋糕的质量。
输出
对于例子,输出一行,表示小明分了多少蛋糕,小方分了多少蛋糕。中间空格隔开。结果保留到小数点后6位。


其实这两题在本质上并没有太大的区别,就是那个式子求和的结果不一样而已,

最后发现1/n*n可以用……求出

int ans = 0;
int x = 1;
for(int i = 1 ; i < 1000000; i++)
{
     ans += x*1.0/i;
     x*=-1;
}

 
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<iostream>
using namespace std;
int main()
{
    double n = 100000000.0;
    double ans = 0.0;
    int N;
    int M;
    cin>>N;
    while(N--)
    {
        cin>>M;

          printf("%.6lf %.6lf\n",0.82246703342408*M,M-0.82246703342408*M);

    }
}        


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值