NYOJ-110-劍客決鬥_動態規劃

來源:互聯網
上載者:User

描述
在路易十三和紅衣主教黎塞留當權的時代,發生了一場決鬥。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

這個題有些類似於弗洛伊德演算法,將環轉化為鏈,通過dp實現,vic[i][j]表示第i個人是否可以與第j個人存在pk機會,當i=j時,也就是出現了自己是否可以和自己pk,如果為真,則表示此環可以最後只剩下第i個人,所以他沒有下一個pk對象,只能和自己pk,否則,說明這個人不能和自己pk,也就是說,不會出現最後只剩下第i個人的情況。

具體代碼實現如下:

#include <stdio.h>#include <string.h>int vic[501][501];  //vic[i][j]第i個與第j個是否有機會PKint rel[501][501];  //劍客間的勝負關係//初始化void init(int n){    int i, j;    for (i = 0; i < n; i++)    {        for (j = 0; j < n; j++)        {            scanf("%d", rel[i] + j);        }    }    memset(vic, 0, sizeof(int) * 501 * 501);    for (i = 0; i < n; i++) //初始化時只能確定相鄰的兩個人是可以PK的    {        vic[i][(i + 1) % n] = 1;    }    return ;}int solve(int n){    int i, j, start, end;    for (i = 1; i < n; i++) //中間隔著i個人    {        for (start = 0; start < n; start++)        {            end = (start + i + 1) % n;            if (vic[start][end])    //當確認兩個能PK時            {                continue;            }            for (j = (start + 1) % n; j != end; j++, j %= n)            {                if (vic[start][j] && vic[j][end] && (rel[start][j] || rel[end][j])) //當start可以和jPK,j可以和endPK,並且至少有一方可以大過j方能實現start和endPK                {                    vic[start][end] = 1;                    break;                }            }        }    }    int cnt = 0;    for (i = 0; i < n; i++)    {        if (vic[i][i])  //為1說明i可以勝出        {            cnt++;        }    }    return cnt;}int main(int argc, const char * argv[]){    int N, n;    scanf("%d", &N);    while (N--)    {        scanf("%d", &n);        init(n);        printf("%d\n", solve(n));    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.