uva 11249 - Game(組合遊戲)

來源:互聯網
上載者:User

標籤:style   http   color   os   io   for   ar   line   

題目連結:uva 11249 - Game

題目大意:給定K和N,表示有N輪遊戲,每輪遊戲給定兩堆石子的個數,兩人輪流操作,每次操作可以選擇一堆取任意數量的石子,也可以選兩堆取,要求兩堆取的石子數之差的絕對值小於K,不能操作者為輸,問先手的勝負情況。

解題思路:傻逼先手才一次取完,那樣的話對手直接將另一堆取光不就傻逼了。所以先手就有一個取石子的最優策略,當兩堆石子的數量差小於等K的時候,先手可以一次性取完所有的。
我們設f(x)為一堆石子的數量為x時的必敗態,即x,f(x),為先手必敗態,x<f(x),那麼對於狀態x,b,如果b>f(x)的,則一定是必勝態,因為先手可以將b取成f(x)。如果b<x,那麼同樣的可以將x取成f(b),那麼就出現了x<b<f(x)的情況,所以根據這個限定,我們可以推匯出f(x),利用單調的性質,這接從前一項擷取f(x),以為當狀態x,b無法轉移成x-1,f(x-1)時,此時的b即為f(x),需要注意的是,我們的x<f(x),那麼對應的,當x=f(t),t<x,那麼f(x)=t

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 1e5;int N, K, v[maxn+5];void init () {    memset(v, -1, sizeof(v));    int mv = 0;    v[0] = 0;    for (int i = 1; i <= maxn; i++) {        if (v[i] == -2)            continue;        int tmp = v[mv] + i - mv + K + 1;        if (tmp > maxn)            break;        v[i] = tmp;        v[tmp] = -2;        mv = i;    }}int main () {    int cas, a, b;    scanf("%d", &cas);    while (cas--) {        scanf("%d%d", &K, &N);        init();        for (int i = 0; i < N; i++) {            scanf("%d%d", &a, &b);            int p = min(a, b);            int q = max(a, b);            printf("%s\n", v[p] == q ? "LOSING" : "WINNING");        }        printf("\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.