首页 > 代码库 > 海盗分金问题(博弈)

海盗分金问题(博弈)

NBUOJ 2680:海盗分金

题意:

有N个海盗要分M金币,将N个海盗从1-N编号,由第一个人提出分配方案,一人一票(分配者也拥有一票),超过半数同意方案才被通过,否则他将被扔入大海喂鲨鱼,接下来由下一人分配,以此类推。

分析:从3个人的状态往后推,每次处理出当前分配方案下的被分到0,1 金币的海盗数量,当前被分到0,下次并然分到1,当前分到1的判断是否需要分配2才能满足通过条件,最后输出分配剩余的金币数即可。

代码:

 1 #include "cstdio"
 2 #include "algorithm"
 3 #include "string"
 4 #include "cstring"
 5 #include "queue"
 6 #include "cmath"
 7 #include "vector"
 8 #include "map"
 9 #include "set"
10 #include "stack"
11 #define db double
12 #define inf 0x3f3f3f
13 typedef long long ll;
14 using  namespace std;
15 const int N=1e3+5;
16 stack<int> s;
17 int a[3],b[3];
18 int main()
19 {
20     int n,m;
21     while(scanf("%d%d",&n,&m)==2)
22     {
23         if(n==1) printf("%d\n",m);
24         else if(n==2) puts("0");
25         else if(n==3) printf("%d\n",m);
26         else
27         {
28             a[0]=2;
29             int ans=0,sum,v,t;
30             for(int i=4;i<=n;i++){
31                 sum=m;
32                 ans=i/2;
33                 v=min(ans,a[0]);
34                 ans-=v,sum-=v;
35                 if(!ans){
36                     b[1]=v;
37                     b[0]=(i+1)/2-1;
38                     a[1]=b[1];
39                     a[0]=b[0];
40                     memset(b,0, sizeof(b));
41                     continue;
42                 }
43                 t=min(ans,a[1]);
44                 ans-=t,sum-=t*2;
45                 if(!ans){
46                     b[1]=v;
47                     b[0]=(i+1)/2-1;
48                     b[2]=t;
49                     a[1]=b[1];
50                     a[0]=b[0];
51                     a[2]=b[2];
52                     memset(b,0, sizeof(b));
53                     continue;
54                 }
55             }
56             printf("%d\n",sum);
57         }
58     }
59     return 0;
60 }

 

代码二:

打表之后得到规律:

 1 #include "cstdio"
 2 int main()
 3 {
 4     int n,m;
 5     while(scanf("%d%d",&n,&m)==2)
 6     {
 7         if(n==1||n==3) printf("%d\n",m);
 8         else if(n==2) puts("0");
 9         else if(n==4) printf("%d\n",m-2);
10         else if(n==5) printf("%d\n",m-3);
11         else printf("%d\n",m-3-(n-4)/2);
12     }
13     return 0;
14 }

 

海盗分金问题(博弈)