zoukankan      html  css  js  c++  java
  • 海盗分金--大于半数才成立

    B  海盗分金币啦

    Time Limit:1000MS  Memory Limit:65535K

    题型: 编程题   语言: 无限制

    描述

    现在有n个海盗,他们抢到了m个金币,现在他们准备分钱,但是由于他们聪明绝顶,

    又不想直接平均分配,都想分到更多的钱,于是他们就想出了一种方法,就是让他们

    按顺序排成一排,编号为1~n,现在由第一个人开始,每个人提出一种方案,如果这个

    方案有除分钱的人以外一半或者一半以上的人同意,那么他们就按照这个方案分钱,否

    则的话,分钱的人就要被拖去喂鲨鱼,继续由下一个人分钱,直到有人提出一个满意的方案。

     

    现在你是第一个分钱的人,你需要保证自己存活的情况下令自己获得的钱数尽可能的多。

    PS

    1.生命>金钱

    2.当其他海盗能获得的金钱比分钱的海盗分给他的金钱多或者一样时,他会反对你分配的方案。



    输入格式

    第一行输入一个T(1<=T<=10000)

    接下来T行输入n和m(1<=n<=1000,1<=m<=10000)

    输出格式

    输出你能得到的金钱数,当你死亡时,输出-1,每个case一行。

    输入样例

    2

    5 100

    2 100

    输出样例

    97

    -1

    Hint

    当5个人分100个金币的时候

    假定五个人按照分钱顺序写为1~5号

    从后向前推,如果1至3号强盗都喂了鲨鱼,只剩4号和5号的话,5号一定投反对票让4号喂鲨鱼,以独

    吞全部金币,四号必死。所以,4号惟有支持3号才能保命。

    3号知道这一点,就会提出“100,0,0”的分配方案,对4号、5号一毛不拔而将全部金币归为已有,

    因为他知道4号即使一无所获,但为了生命着想还是会投赞成票,他的方案即可通过。

    不过,2号推知3号的方案,就会提出“98,0,1,1”的方案,即放弃3号,而给予4号和5号各一枚金

    币。由于该方案对于4号和5号来说比在3号分配时更为有利,他们将支持他而不希望他出局而由3号来

    分配。这样,2号将拿走98枚金币。

    同样,2号的方案也会被1号所洞悉,1号并将提出(97,0,1,2,0)或(97,0,1,0,2)的方案,

    即放弃2号,而给3号一枚金币,同时给4号(或5号)2枚金币。由于1号的这一方案对于3号和4号(或5号)

    来说,相比2号分配时更优,他们将投1号的赞成票,1号的方案可获通过,97枚金币可轻松落入囊中。这

    无疑是1号能够获取最大收益的方案了!

    答案是:1号强盗分给3号1枚金币,分给4号或5号强盗2枚,自己独得97枚。分配方案可写成

    (97,0,1,2,0)或(97,0,1,0,2)。

     

    当只有2个人分100金币时:

    推理同上:你不可能存在令最后一人满意的方案

     

    一道模拟题,wa了我很多次,原因是因为我没想到如果某个海盗一定死了时,它会成为上一个海盗的“死党”,所以上一个海盗可以省一个金币,甚至有可能活过来。开始的时候我但但是模拟了题目的数据,一直写到13 100,果然太天真,100个金币你分很多个都分不完了,所以我就开始用金币为5来模拟,就发现了13 5 是0,14 5 是-1但是17 5是0,又奇迹地复活了,因为它有三个连续的死党了。

      所以,分析完后,根据DP的思路,从后开始计数。一路向上推,打个表(不然超时),用个数组

    a[i][j],表示,有i个海盗,j个金币的时候最多能拿多少钱。从而判断a[i-1][j];他的上一个能拿多少钱?如果它死了,就要找出有多少个连续的死党,我就不需要用钱贿赂它了,如果他是0,也好办,贿赂它只需要用money=need*1;其中need=i/2;就是当前人数的一半,这样能确保他>50%的,模拟下吧。如果他>0,那么,就有一个海盗要用2个金币来贿赂啦,所以money=need+1;

    打个表,以后查询o(1)..233ms过了。。说多都是泪啊。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    int a[1002][10002];
    int find (int pos,int money)//找到有多少个连续的”死党“
    {
        int i;
        int i_count=0;
        for (i=pos;i>=1;i--)
        {
            if (a[i][money]!=-1)
            {
                return i_count;
            }
            i_count++;
        }
        return i_count;
    }
    void init ()
    {
        int i,j;
        int t;
        for (j=1;j<=10000;j++)
        {
            a[1][j]=j;//拿到
            a[3][j]=j;//get
        }
        for (j=1;j<=10000;j++)
        {
            a[2][j]=-1;//死忙
        }
        for (j=1;j<=10000;j++)
        {
            a[4][j]=j-2;//1---4要特殊处理,,自己看看"规律"吧
        }
        int need;
        int money;
        for (i=5;i<=1000;i++)
        {
            for (j=1;j<=10000;j++)
            {
                 need=i/2;//需要贿赂的人数
                 if (a[i-1][j]==0)
                 {
                     money=need;//就需要这么多个1
                 }
                 else if (a[i-1][j]==-1)//他会死的话..可以小很多个
                 {
                     t=find(i-1,j);
                     money=need-t;//还可以少t个
                 }
                 else
                 {
                     money=need+1;//4个海盗时是不符合这个规矩的
                 }
                 
                 if (j<money)//不够钱..死了
                 {
                     a[i][j]=-1;
                 }
                 else 
                 {
                     a[i][j]=j-money;
                 }
            }
        }
        return ;
    }
    void work ()
    {
        int n,m;
        scanf ("%d%d",&n,&m);
        printf ("%d
    ",a[n][m]);
        return ;
    }
    int main ()
    {
        init ();
        int t;
        scanf ("%d",&t);
        while (t--)
        {
            work ();
        }
        return 0;
    }
  • 相关阅读:
    HDU 2639 Bone Collector II (01背包,第k解)
    POJ 2184 Cow Exhibition 奶牛展(01背包,变形)
    hihoCoder #1165 : 益智游戏 (挑战赛11 B题)
    UVA 562 Dividing coins 分硬币(01背包,简单变形)
    POJ Charm Bracelet 挑饰品 (常规01背包)
    hiho一下 第四十四周 博弈游戏·Nim游戏(直接公式解)
    UVA 624 CD(01背包,要记录路径)
    118 Pascal's Triangle 帕斯卡三角形 杨辉三角形
    117 Populating Next Right Pointers in Each Node II 每个节点的右向指针 II
    116 Populating Next Right Pointers in Each Node 每个节点的右向指针
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/5137999.html
Copyright © 2011-2022 走看看