NYoj 110 劍客決鬥 DP

2021-07-16 03:16:41 字數 1759 閱讀 4368

劍客決鬥

時間限制:5000 ms | 記憶體限制:65535 kb

難度:5

描述 在路易十三和紅衣主教黎塞留當權的時代,發生了一場決鬥。n個人站成乙個圈,依次抽籤。抽中的人和他右邊的人決鬥,負者出圈。這場決鬥的最終結果關鍵取決於決鬥的順序。現書籍任意兩決鬥中誰能勝出的資訊,但「a贏了b」這種關係沒有傳遞性。例如,a比b強,b比c強,c比a強。如果a和b先決鬥,c最終會贏,但如果b和c決鬥在先,則最後a會贏。顯然,他們三人中的第一場決鬥直接影響最終結果。

假設現在n個人圍成乙個圈,按順序編上編號1~n。一共進行n-1場決鬥。第一場,其中一人(設i號)和他右邊的人(即i+1號,若i=n,其右邊人則為1號)。負者被淘汰出圈外,由他旁邊的人補上他的位置。已知n個人之間的強弱關係(即任意兩個人之間輸贏關係)。如果存在一種抽籤方式使第k個人可能勝出,則我們說第k人有可能勝出,我們的任務是根據n個人的強弱關係,判斷可能勝出的人數。

輸入 第一行是乙個整數n(1<=n<=20)表示測試資料的組數。

第二行是乙個整數n表示決鬥的總人數。(2<=n<=500)

隨後的n行是乙個n行n列的矩陣,矩陣中的第i行第j列如果為1表示第i個人與第j個人決鬥時第i個人會勝出,為0則表示第i個人與第j個人決鬥時第i個人會失敗。

輸出 對於每組測試資料,輸出可能勝出的人數,每組輸出佔一行

樣例輸入

1 3

0 1 0

0 0 1

1 0 0

樣例輸出

3 **

《世界大學生程式設計競賽高階教程·第一冊》

分析:

考慮 x 是否能贏得戰鬥,把環看成鏈,x點拆成兩個,分別作為鏈的起點和終點。

這樣,則 x 能從所有人中勝出的充要條件就是 x 能與自己「相遇」。

設meet[i,j] 記錄 i 和 j 能否相遇,能則為true,否則為false。(i 和 j 為上述提到的鏈的起點和終點)

在乙個環中,相鄰的兩個人是可以相遇的,所以初始時meet[i][i+1]=true;

則問題轉化成了是否能在i,j之間找到乙個k,使得 i 和 k , k 和 j 均能相遇,且 i 或者 j 能打敗 k (i能打敗k則i打敗k後可以與j相遇;由於k,j相鄰,所以k,j之間可以產生決鬥,當j打敗k後i,j也相遇了)。

狀態轉移方程: meet[i][j]=meet[i][k] && meet[k][j] && (beat[i][k] || beat[j][k]);

如:

開始時距離為一的都可以相遇,我們將所有距離為2的i,j進行上式的轉換,那麼一次迴圈之後,滿足條件的所有距離為2的也可以相遇了。依次類推,我們可以將所有的可相遇情況更新出來。

ac**:

#include 

#include

#include

using

namespace

std;

const

int n = 510;

bool beat[n][n],meet[n][n];

int main()}}

}int ans=0;

for(int i=0;iif(meet[i][i]) ans++;

printf("%d\n",ans);

}return

0;}

NYoj110 劍客決鬥

分析 這道題真是沒想到是動態規劃,已開始認為是圖論,想了好久只有最大流才能求出值,但是構不圖。還是太弱啊 看了一篇部落格 才知道是區間動態規劃。考慮 x 是否能贏得戰鬥,把環看成鏈,x點拆成兩個,分別作為鏈的起點和終點。這樣能勝出的條件就是自己和自己相遇。狀態為meet i j 表示i,j能相遇,這...

NYOJ 110 劍客決鬥

描述 在路易十三和紅衣主教黎塞留當權的時代,發生了一場決鬥。n個人站成乙個圈,依次抽籤。抽中的人和他右邊的人決鬥,負者出圈。這場決鬥的最終結果關鍵取決於決鬥的順序。現書籍任意兩決鬥中誰能勝出的資訊,但 a贏了b 這種關係沒有傳遞性。例如,a比b強,b比c強,c比a強。如果a和b先決鬥,c最終會贏,但...

nyoj 110 劍客決鬥

click here n個人站成乙個圈,依次抽籤。抽中的人和他右邊的人決鬥,負者出圈。這場決鬥的最終結果關鍵取決於決鬥的順序。現輸入任意兩決鬥中誰能勝出的資訊,但 a贏了b 這種關係沒有傳遞性。例如,a比b強,b比c強,c比a強。如果a和b先決鬥,c最終會贏,但如果b和c決鬥在先,則最後a會贏。顯然...