海盜分金問題(博弈)
阿新 • • 發佈:2017-08-01
for log fine using ble 規律 vector printf 問題
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 }
海盜分金問題(博弈)