hdu-1538 A Puzzle for Pirates

題目連接:php

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

題目類型:ide

模擬spa

題意歸納:.net

有1~n,n個海盜,m塊金子,第n個海盜要提出一個分金方案,若是有一半以上的人贊成,就馬上分金,反之就將這我的扔下水裏,問全部狀況都是最優解的狀況下,要給第p個海盜分多少金?code

解題思路:blog

若是隻有一我的,因此確定是給本身。ip

若是有兩我的,那麼本身將全部的錢都給本身,那麼本身也贊成分配,就能夠獲得一半以上的人的贊成。ci

若是有三我的,第一我的知道若是不一樣意三號,那麼本身絕對分不到錢,因此三號給多少,一號都會贊成,有比沒有強嘛,因此,三號只須要給一號一枚金幣,剩下的全都收到囊中便可。get

若是有四我的,若是第四我的死了,就像上種狀況同樣,因此只須要給二號一枚金幣,就能夠得到一半的支持。

........

以此類推,只要第n個海盜給本身編號奇偶性相同的海盜各一枚金幣,便可。那麼問題就來了...

若是獲得的金子不夠賄賂怎麼辦,也就是m*2<n的狀況下,那就不是錢不錢的問題了,那就是小命要緊了,具體分析一下:

假若有500個海盜,可是隻有100枚金幣,怎麼辦?

對於201號來講,本身不能拿金幣,而且把金幣給除本身以外的其餘奇數號海賊就能存活

對於202號來講,本身一樣不能拿金幣,而且吧金幣給除了本身以外的其餘偶數號海賊就能存活

對於203來講,至少須要102我的的支持,可是本身賄賂的拿金子得到的海盜加上本身,只能拿到101票,因此203必死,

對於204,若是本身死了,203必死,因此203必定會支持本身,因此本身吧金幣分給以前的前200號偶數,一共能夠獲得100+1(203)+1(204),本身能夠保證不死。

對於205號,204,203已經有了保全之策,因此他們是不會支持205的,因此205必死。

對於206呢,雖然205必死,會支持他,可是仍是缺一票,因此必死。
對於207呢,205和206以前是必死,會支持他,可是加上本身以及100個保命名額,仍是必死
對於208號,205,206.,207由於後面是必死的,確定會支持208成功,那麼208恰好能湊齊104票,得以保命。
因此,由此獲得結論:n=2*m+2^k的狀況下,是能夠保命的狀態,反之則爲危險狀態緣由以下:
首先對於n來講,有m票賄賂,可是對於2*m+2^(k-1)之前必死的死,他們會支持2*m+2^(k-1),由於他們確定拿不到錢,並且支持2*m+2^(k-1),另外根據殺人原則,但願以後的人都死,輪到2*m+2^(k-1)決策的時候保命就好了。
同理2*m+2^(k-1)到2*m+2^k之間的2^(k-1)-1我的來講,他們必死,因此一定支持2*m+2^k,加上m個金幣賄賂的,加上他本身,恰好有m+2^(k-1)。這樣恰好湊齊一半,能夠不死。
因此:2*m+2^k的人能夠保命,不然必死。
 
咱們考慮一下分金幣狀況:
對於第2*m+2^k我的來講,他能夠保命,確定分不到金子,而他手上的m個金子,能夠賄賂m我的,可是具體是哪些人是不定的。則不論是不能分到金子,仍是可能分不到金子的人來講,結果都爲0。
對於2*m+2^(k-1)到2*m+2^k之間的來講,他們的決策是必死,而在他們決策的時候,其它人分得金幣狀況也爲0。
 
咱們來解釋一下金幣的不肯定性:

金幣數量的不肯定性:由上面的推理可知, 當n=2m+2時, 上一輪推理沒有分到金幣的人的金幣數量首次具備不肯定性, 而且在n>2m+2時, 這種不肯定性必定會延續下去, 輪到由於n號決策者以前的一我的決策時, 那我的確定分不到金幣了, 因此在上一輪推理中沒有分到金幣的人的個數必定大於m。

綜上所述就是該題的解題思路,很是感謝大神的解題思路,給我帶來了太多的靈感,參考連接:

http://blog.csdn.net/acm_cxlove/article/details/7853916#comments

題目:

A Puzzle for Pirates

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 996    Accepted Submission(s): 384


Problem Description
A bunch of pirates have gotten their hands on a hoard of gold pieces and wish to divide the loot. They are democratic pirates in their own way, and it is their custom to make such divisions in the following manner: The fiercest pirate makes a proposal about the division, and everybody votes on it, including the proposer. If 50 percent or more are in favor, the proposal passes and is implemented forthwith. Otherwise the proposer is thrown overboard, and the procedure is repeated with the next fiercest pirate. 
All the pirates enjoy throwing one of their fellows overboard, but if given a choice they prefer cold, hard cash, the more the better. They dislike being thrown overboard themselves. All pirates are rational and know that the other pirates are also rational. Moreover, no two pirates are equally fierce, so there is a precise pecking order — and it is known to them all. The gold pieces are indivisible, and arrangements to share pieces are not permitted, because no pirate trusts his fellows to stick to such an arrangement. It's every man for himself. Another thing about pirates is that they are realistic. They believe 'a bird in the hand is worth two in the bush' which means they prefer something that is certain than take a risk to get more, where they might lose everything. 

For convenience, number the pirates in order of meekness, so that the least fierce is number 1, the next least fierce number 2 and so on. The fiercest pirate thus gets the biggest number, and proposals proceed in the order from the biggest to the least. 

The secret to analyzing all such games of strategy is to work backward from the end. The place to start is the point at which the game gets down to just two pirates, P1 and P2. Then add in pirate P3, P4, ... , one by one. The illustration shows the results when 3, 4 or 5 pirates try to divide 100 pieces of gold. 



Your task is to predict how many gold pieces a given pirate will get.
 

 

Input
The input consists of a line specifying the number of testcases, followed by one line per case with 3 integer numbers n, m, p. n (1 ≤ n ≤ 10^4) is the number of pirates. m (1 ≤ m ≤ 10^7) is the number of gold pieces. p (1 ≤ p ≤ n) indicates a pirate where p = n indicates the fiercest one. 
 

 

Output
The output for each case consists of a single integer which is the minimal number of gold pieces pirate p can get. For example, if pirate p can get 0 or 1 gold pieces, output '0'. If pirate p will be thrown overboard, output 'Thrown'. 
 

 

Sample Input
3
3 100 2
4 100 2
5 100 5
 

 

Sample Output
0
1
98
Hint
Hint
The situation gets complicated when a few gold pieces were divided among many pirates.
 
#include<iostream>  
#include<cstdio>  
#include<ctime>  
#include<cstring>  
#include<cmath>  
#include<algorithm>  
#include<cstdlib>  
#include<vector>  
#define C    240  
#define TIME 10  
#define inf 1<<25  
#define LL long long  
using namespace std;  
//保存2的冪  
int fac[15]={2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768};  
void slove(int n,int m,int p){  
    //金幣夠賄賂的狀況  
    if(n<=2*m){  
        //不是決策者,並且奇偶性相同,都能被賄賂  
        if(n!=p&&(n%2==p%2))  
            printf("1\n");  
        //剩下的都是決策者擁有  
        else if(n==p)  
            printf("%d\n",m-(n-1)/2);  
        else  
        //其他人分不到金幣,他們的決策不影響全局  
            printf("0\n");  
        return ;  
    }  
    //這時候的不一樣在於決策者不能拿金幣  
    else if(n==2*m+1){  
        if(p<2*m&&p&1)  
            printf("1\n");  
        else  
            printf("0\n");  
        return ;  
    }  
    int t=n-2*m,i;  
    //這是恰好保命的狀況,對於決策者來講,確定沒有金幣  
    //對於其它人來講,要麼確定沒有金幣,要麼可能沒有金幣,不肯定性  
    for( i=0;i<14;i++){  
        if(t==fac[i]){  
            printf("0\n");  
            return;  
        }  
    }  
    for( i=1;i<14;i++)  
        if(t<fac[i]){  
            //決策者必死  
            if(p>2*m+fac[i-1]&&p<2*m+fac[i])  
                 printf("Thrown\n");  
            else  
                 printf("0\n");  
            return ;  
        }  
}  
int main(){  
    int t,n,m,p;  
    scanf("%d",&t);  
    while(t--){  
        scanf("%d%d%d",&n,&m,&p);  
        slove(n,m,p);  
    }  
    return 0;  
}  
相關文章
相關標籤/搜索