• 问题 D: 小k的硬币问题


    问题 D: 小k的硬币问题

    时间限制: 1 Sec  内存限制: 128 MB
    提交: 21  解决: 5
    [提交] [状态] [命题人:jsu_admin]

    题目描述

    小k和小p一起玩一个游戏,有n堆硬币,每人轮流拿硬币,每次可以拿走1~5枚硬币,(必须拿完前一堆硬币才能开始拿后面一堆硬币,如果当前这堆硬币只剩下一枚,那么此次机会只能拿一枚),谁拿走的硬币多则获胜,两个人都足够聪明,后拿的人有一次机会能够一次拿走当前这堆硬币,请问比赛的结果是什么。

    输入

    第一行包含一个整数 T,表示有 T组测试数据。
    接下来依次描述 T 组测试数据。对于每组测试数据:
    第一行为两个整数 n,k,表示有n堆硬币,k为1则表示小k先拿,k为0则表示小k后拿。
    接下来一行,有n个整数m1.....mn,表示每堆硬币的数量。 

    0<T<10,0<n<=1000,0<m<=10

    输出

    如果小k能赢则输出1,平手则输出0,否则输出-1.

    样例输入 Copy

    4
    1 1
    10
    5 0
    9 9 3 5 6
    6 0
    1 1 1 1 1 1
    2 1
    10 1
    

    样例输出 Copy

    0
    1
    0
    1


    这道题要用到博弈论的思维来解答,先来分析每一堆硬币,数量为 1~10,当数量为 1 是,没法选择策略,只能拿 1 个,当数量为 2~5 时先选的人可以选择拿走 n-1 个,下 一堆硬币有优先选择权,也可以选择拿走 n 个,下一堆硬币后选,当数量为 6 时,只 有一种策略,就是拿走 5 个(因为拿走 5 个以下时,另一个人就能决定你下一堆硬币 的先后手,题目已经申明两个人都足够聪明),这是下一堆硬币先选,当数量为 7~10 的时候,可以选择拿走 n-6 个,此时对方只能拿走 5 个,然后自己拿走剩下的 1 个,

    
    

    下一堆硬币后选,也可以直接拿走   5  个,让对方决定自己下堆硬币是先手还是后手。

    因为考虑到一开始后手的人有一次一次性拿走一堆硬币的机会,所以以该角色进行倒 推(倒推的话,每个人在选择的时候都能看出自己之后怎么选才是最合适的),分为

    4 个状态,该堆硬币有优先选择权,且有一次机会已经用过,2.该堆硬币没有优先选择 权,且一次机会已经用过,3.该堆硬币有优先选择权,且有一次机会,4.该堆硬币没有 优先选择权,且没有机会,保存每种状态下能拿到的最多的硬币数量。从后往前开始 逆推时,要考虑的如果有一次机会的话,可以通过这一次机会来改变自己下一堆硬币 的先后手,且如果是后手,对方只会选择让你拿到最少硬币的策略。当逆推结束是, 第二种状态能拿到的最多的硬币数量就是,后手这个角色能拿到的最多的硬币数量。

     我的暴搜tle

      1 #include<stdio.h>
      2 #include<string.h>
      3 int a[1010];
      4 int b[2];
      5 int m,n;
      6 int sum = -1;
      7 //a,b
      8 //a = 0,c = 1; 
      9 void dfs(int i,int c,int d,int temp){
     10 //    printf("%d ",c);
     11 //    printf("%d ",d);
     12 //    printf("%d ",a[i]);
     13 //printf("%d ",temp);
     14     if(i==m+1)
     15     {
     16         if(n==0){
     17         
     18         if(c<d){
     19     //    printf("%d %d",c,d);
     20         sum = 1;
     21     //    i--;
     22         return ;
     23     }
     24     else if(sum!=1&&c == d)
     25     {
     26         sum = 0;
     27     //    i-- ;
     28         return ;
     29     }
     30 //    i--;
     31     return ;
     32     }
     33     else
     34     {
     35             if(c>d){
     36     //    printf("%d %d",c,d);
     37         sum = 1;
     38     //    i--;
     39         return ;
     40     }
     41     else if(sum!=1&&c == d)
     42     {
     43         sum = 0;
     44     //    i-- ;
     45         return ;
     46     }
     47 //    i--;
     48     return ;
     49     }
     50     
     51 }
     52     
     53     if(a[i]==1)
     54     {
     55         //temp 0  dy  c dy !k 
     56         if(temp == 0){
     57         
     58         dfs(++i,c++,d,1-temp),i--,c--,1-temp;
     59         return; 
     60     }
     61         else{
     62         
     63         dfs(++i,c,d++,1-temp),i--,c,d--,1-temp;
     64         return; 
     65     }
     66             //d[n]++,n = 1-n;
     67     }
     68         
     69             else if(2<=a[i]&&a[i]<=5){
     70                 //1
     71             //    d[n]+=a[i]-1,d[1-n] +=1;
     72             if(temp==0) //a+=a[i] - 1 d += 1{
     73             {
     74             
     75                 dfs(++i,c+=a[i] - 1, d += 1,temp),i--,c-=a[i] - 1, d -= 1;
     76                 //2
     77                 dfs(++i,c+=a[i],d,1-temp),i--,c-=a[i],d,1-temp;
     78             //    d[n]+=a[i],n = 1-n;
     79             return; 
     80                     }
     81                     else{
     82                         dfs(++i,d+=a[i] - 1, c += 1,temp),i--,d-=a[i] - 1, c -= 1;
     83                 //2
     84                 dfs(++i,d+=a[i],c,1-temp),i--,d-=a[i],c,1-temp;
     85                 return; 
     86                     }
     87             }
     88             else if(a[i]==6){
     89 //                d[n] += 5;
     90 //                d[1-n]++;
     91             if(temp == 0){
     92                     dfs(++i,c+=5,d++,temp),i--,c-=5,d--;
     93                     return; 
     94             }
     95             else{
     96             
     97             dfs(++i,d+=5,c++,temp),i--,d-=5,c--;
     98         //    i--
     99         return; 
    100     }
    101             }
    102             else if(a[i]>=7&&a[i]<=10){
    103                 //1
    104                 if(temp ==0){
    105                 
    106                     dfs(++i,c+=a[i]-6+1,d+=5,1-temp),i--,c-=a[i]-6+1,d-=5,1-temp;
    107                 //d[n] += a[i] - 6,d[1-n] += 5,d[n]+=1,n = 1-n;
    108                 //2
    109             //    i--;
    110                     dfs(++i,c+=5,d+=a[i]-5,temp),i--,c-=5,d-=a[i]-5;
    111             //        i--;
    112                 //d[n] += 5;
    113                 //2.1
    114             //    d[1-n] +=a[i] - 5;
    115                 dfs(++i,c+=6,d+=a[i]-6,1-temp),i--,c-=6,d-=a[i]-6,1-temp;
    116             //    i--;
    117             return; 
    118             }
    119             else    if(temp ==1){
    120                 
    121                     dfs(++i,d+=a[i]-6+1,c+=5,1-temp),i--,d-=a[i]-6+1,c-=5,1-temp;
    122             //        i--;
    123                 //    printf("%d",d);
    124                 //d[n] += a[i] - 6,d[1-n] += 5,d[n]+=1,n = 1-n;
    125                 //2
    126                     dfs(++i,d+=5,c+=a[i]-5,temp),i--,d-=5,c-=a[i]-5;
    127                 //    i--;
    128                 //d[n] += 5;
    129                 //2.1
    130             //    d[1-n] +=a[i] - 5;
    131             if(m!=1)
    132                 dfs(++i,d+=6,c+=a[i]-6,1-temp),i--,d-=6,c-=a[i]-6,1-temp;
    133                 //dfs(++i,d+=6,c+=a[i]-6,1-temp),i--,d-=6,c-=a[i]-6,1-temp;
    134             //    i--;
    135             return; 
    136             }
    137                 //2.2
    138             //    d[1-n] +=a[i] - 5 -1,d[n]++,n = 1-n;
    139             }
    140             
    141 }
    142 int main(){
    143     int t;
    144     
    145     
    146     scanf("%d",&t);
    147     while(t--){
    148         //分别为堆数 
    149         memset(a,0,sizeof(a));
    150         sum = -1;
    151         scanf("%d%d",&m,&n);
    152         for(int i = 1;i<=m;i++){
    153             scanf("%d",&a[i]);
    154         }
    155         int temp = n;
    156         dfs(1,0,0,temp);
    157 //        for(int i = 1;i<=m;i++){
    158 //            if(a[i]==1)
    159 //            d[n]++,n = 1-n;
    160 //            else if(2<=a[i]&&a[i]<=5){
    161 //                //1
    162 //                b[n]+=a[i]-1,b[1-n] +=1;
    163 //                //2
    164 //                b[n]+=a[i],n = 1-n;
    165 //                        
    166 //            }
    167 //            else if(a[i]==6){
    168 //                b[n] += 5;
    169 //                b[1-n]++;
    170 //                
    171 //            }
    172 //            else if(a[i]>=7&&a[i]<=10){
    173 //                //1
    174 //                b[n] += a[i] - 6,b[1-n] += 5,b[n]+=1,n = 1-n;
    175 //                //2
    176 //                b[n] += 5;
    177 //                //2.1
    178 //                b[1-n] +=a[i] - 5;
    179 //                //2.2
    180 //                b[1-n] +=a[i] - 5 -1,b[n]++,n = 1-n;
    181 //            }
    182 //            
    183 //        }
    184         if(sum){
    185             printf("1
    ");
    186         }
    187         else if(sum==0)
    188         {
    189             printf("0
    ");
    190         }
    191         else if(sum ==-1)
    192         {
    193             printf("-1
    ");
    194         }
    195     }
    196 }
    View Code
  • 相关阅读:
    最近用到mysql和mybatis结合常用的知识点坐下整理
    采用rest接口对接而非webservice
    Linux 下Nginx 的安装及负载均衡的简单配置
    用websocket实现后台推送消息
    maven项目添加websocket
    Java通过几种经典的算法来实现数组排序
    关于 Java 数组的 12 个最佳方法
    Ajax详解及其案例分析之如何获得Ajax对象,使用Ajax对象发送GET和POST请求,校验用户名,POST和GET请求时的乱码处理,实现级联的下拉列表
    Python
    【作业报告】作业5 四则运算 测试与封装 5.1
  • 原文地址:https://www.cnblogs.com/DWVictor/p/10202480.html
Copyright © 2020-2023  润新知