zoukankan      html  css  js  c++  java
  • HDU-4371-Alice and Bob

    题目链接

    http://acm.hdu.edu.cn/showproblem.php?pid=4371

    这题在比赛的时候看错了题意,卡了很久都没做出来,也没有再回头仔细去看题,所以没做出来,之后再看别人的博客才知道,题意弄错了。

    英语一定要给我多记单词,多去翻译文章句子。

    题意:题意:Alice 和 Bob 轮流写数字,假设第 i 次的数字是 S(i) ,那么第 i+1 次的数字 S(i+1)= S(i)+d(k)或 S(i)-d(k),

    条件是 S(i+1)<= n && S(i-1)<S(i+1)。不过题意弄懂了,这个题也不好做。只能引用他人的思路了

    结论:在所有的d中,选择最小的d,这里记作dmin,Alice和Bob每次都选择+dmin(写下的数是在原来的那个数上加上dmin),按照这样的策略最后的结果就是全局的结果。 

    可以这样考虑正确性,不妨假设按照以上策略是Alice获胜,那么Alice并不会主动改变策略;假设Bob在某一步突然改变策略,即没有选择+dmin,那么就必然选择了某个+d(不会是-d,因为这样肯定不合法),且d > dmin,那么下一步Alice就可以选择-dmin了,再下一步,Bob就只能选择某个+d,且d > dmin,Alice则可以一如既往的选择-dmin,如此循环,无论每次Bob做什么样的决策,Alice都可以选择-dmin,所以肯定是Bob最先没有选择,同样是Alice获胜。这样就证明了开头的结论。  

    分析:杂一看真的不好确定必输或必赢状态。那么直接想最后一步,什么时候就结束呢?s(i)+min > n 时就输了;那么s(i-1)又是什么情况呢?s(i-1) 可以选择一个 d(d >min) 或 min 这两种情况,如果选择了 min,那么下一步一定也要向上加,如果选择了是 d 那么有两种情况种是向下面减,和向上面加。于是可以发现先手如果选择了 min 那么后手只能向上加,如果先手选择了 d ,那么后手就可以减去 min ,这样可以保证自己永远有数可以写直到自己赢了。

    代码

    #include<stdio.h>
    int main(void)
    {
    int t,n,m,i,j;
    int s;
    int d[111];
    int min;
    scanf("%d",&t);
    for(i=1;i<=t;i++)
    {
    min=999999999;
    scanf("%d%d",&n,&m);
    for(j=1;j<=m;j++)
    {
    scanf("%d",d+i);
    if(min>d[i])
    min=d[i];
    }
    s=n/min;//Alice先取
    if(s%2==0)//如果s为偶,那么最后是Bob取到n,或少于n,但与n相差不超过min。
    {//所以Alice再取的话,就会 > n 成立。
    printf("Case #%d: Alice ",i);
    }
    else
    {
    printf("Case #%d: Bob ",i);
    }
    }
    return 0;
    }

  • 相关阅读:
    关于MySQL死锁
    随手一记,maven打包
    js生成带logo的二维码
    java生成带logo的二维码
    关于网页中文本域高度自动适应问题,参考微信回复
    从git上拉下来的严选weex项目demo
    补装老版本的Java SE
    新MBP使用git命令时启用xcode的终端log
    电脑出现“损坏的图像”窗口提示dll没有被指定在Windows上运行如何解决
    不同浏览器隐藏默认表单样式
  • 原文地址:https://www.cnblogs.com/liudehao/p/3959694.html
Copyright © 2011-2022 走看看