有一棵n個點的有根樹,他有m個葉子結點(葉子結點是那些沒有孩子的結點)。邊由父親指向孩子。數字1到m被分配到每乙個葉子中。每乙個葉子有乙個數字,並且每乙個數字恰好被分配到乙個葉子中。
剛開始的時候根部有乙個棋子。兩個玩家輪流移動棋子,每一步都會將這個棋子向他的某乙個孩子移動;如果玩家不能再移動棋子了,那麼遊戲結束。遊戲的結果就是棋子所在葉子上面的數字。遊戲的先手想要這個數字最大化,而後手想要這個數字最小化。
山巴布裡想要給這些葉子分配數字使得最終結果最大,而馬族塔想要給這些葉子分配數字使得最終結果最小。那麼當山巴布裡來分配數字的時候遊戲結果會是多少?馬族塔分配的時候又是多少呢?山馬布里和馬族塔並不參加遊戲,而是另外兩個非常聰明的人來參加遊戲。
樣例解釋:在這個樣例中,樹有三個葉子:3,4和5。如果把數字3分配給3號結點,那麼第乙個選手就能夠讓棋子到達那兒,最終結果就是3。另一方面,很明顯,無論怎麼分配數字,第乙個選手讓棋子達到最小數字是2。
考慮最大化怎麼做。
假設我的答案是ans,設f[i]表示i子樹內需要至少安置多少個》=ans才能使在這個節點往後操作一定能使答案為ans。
顯然i是先手操作就對每顆子樹的f取min,否則求和。
顯然m-f[1]是最大答案。
最小化同理。
hljs perl">#include
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int maxn=200000+10;
int f[maxn],d[maxn],h[maxn],go[maxn],next[maxn];
int i,j,k,l,r,mid,n,m,ans,tot;
void add(int
x,int
y)void dfs(int
x) while (t)
}void dg(int
x) if (d[x]%2==0)
}else
}}void dg2(int
x) if (d[x]%2==1)
}else
}}int main()
dfs(1);
dg(1);
printf("%d ",m-f[1]+1);
dg2(1);
printf("%d\n",f[1]);
}
1531 樹上的博弈
51nod 1531 樹上的博弈 樹型dp 1.建樹,複雜度o n 2.自下向上dp,複雜度o n 記錄狀態量 當前該棵子樹 分配m個數,答案是第k小數 進行狀態轉移 由於有先後手,並且有 分配希望 最大與最小 兩種前提。因此2 2 4種狀態,不過最大最小是對稱關係,因此可以只計算其中2種,另2種根...
51nod 1490 多重遊戲(樹上博弈)
1490 多重遊戲 codeforces 基準時間限制 1 秒 空間限制 131072 kb 分值 40 難度 4級演算法題 有乙個兩人遊戲,遊戲是這樣的,有n個非空串。在遊戲的過程是,兩個玩家輪流向乙個字串後面加字母,剛開始字串是空的。每一次操作是向當前字串後面新增字元,形成的新字串一定要是這n個...
51nod 1068 簡單博弈
思路 手動打表,n 1 a出1 a勝 2 a出2 a勝 3 a只能出2的整數冪 這個數 3,所以只能出1,2 a出1的時候,b就是2的情況,b勝 a出2的時候,b就是1的情況,b勝 4 a只能出2的整數冪 這個數 3,所以只能出1,2,4 直接拿4,a勝 5 a只能出2的整數冪 這個數 3,所以只能...