首页 > 代码库 > 海盗分金问题(博弈)
海盗分金问题(博弈)
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 }
海盗分金问题(博弈)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。