HDU 1584 蜘蛛牌 dfs 最優性剪枝

2021-09-28 11:46:54 字數 1304 閱讀 6007

題目大意:給出10張牌,隨機分布在1~10十個不同的位置,要求模擬蜘蛛紙牌的遊戲規則,問移動的最短距離之和是多少

題目分析:我們可以直接dfs搜尋,但需要想清楚該怎麼搜尋,這個題目有點貪心的思想,因為要求移動距離之和最小,所以我們應該盡量避免多餘的移動,簡單來說,我們只需要將當前牌放置到比當前牌序號大1的牌上就行,說起來可能有些抽象,舉個例子,牌1只需要移動到牌2上即可,不需要移動到牌3上然後再移動到牌2上之類的,相對的,牌10的位置就固定了,因為牌10在**都一樣。

然後就是搜尋了,因為不一定是按照順序來的,不一定是牌1放到牌2上,然後牌2帶著牌1放到牌3上,也可能是牌2先放到牌3上,然後牌1再放到牌2上等等等等,所以我們在搜尋時,第一層for需要列舉所當前輪次所需要移動的牌,然後第二層for需要尋找比當前牌序號大1的牌的位置,然後放上去即可,一開始我就是不太會處理第二層for迴圈,以為單純的用i+1來判斷就行,果不其然的wa了一發,其實可以換個思想,比如我們已經將牌4放到牌5上了,那麼我們接下來需要將牌3放到牌4上,我們該處理的距離肯定不是abs(a[3]-a[4])了,因為此時的牌4已經到了牌5的位置,所以正確距離應該是abs(a[3]-a[5])才對,所以我們的vis陣列儲存的是每一堆撲克中最底層的那個牌的大小,並且根據規則,我們可以保證這個牌的序號一定是該堆牌中最大的一張,所以我們在尋找目標牌的位置時,只需要在i+1-10中找到第乙個在最底層的數即可,假設我們找到的目標牌是k,則可以保證第i+1~k張牌已經放到了第k張牌的上面

emmm,可能理解起來有點麻煩,但畢竟也是我想了有乙個小時才想明白的問題。。直接掛**吧,和網上絕大部分的**一樣:

#include#include#include#include#include#include#include#include#include#includeusing namespace std;

typedef long long ll;

const int inf=0x3f3f3f3f;

const int n=15;

int a[n];

int ans;

bool vis[n];

void dfs(int pos,int cnt)

for(int i=1;i<10;i++)//選擇需要移動的牌

vis[i]=false;

} }}int main()

memset(vis,false,sizeof(vis));

ans=100;//答案初始化為100,其實到90就行,強迫症湊個整

dfs(0,0);

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

return 0;

}

HDU1584 蜘蛛牌 DFS簡單題

這個題一開始難哭,想不通為什麼,現在大概理一理,思路如下 1.一共只有十張牌,所以只是隨機排列,並求出其中的距離之和 因為1只能接2,2接3,以此類推 2.eg 1 4 5 2 3 所以應該先從1 2,距離 abs 4 1 3 3.而且因為需要掃瞄,所以令初始標記為0,當滿足要求則變為1,掃一遍後,...

HDU1584 蜘蛛牌 DFS 簡單題

題意 蜘蛛牌是windows xp作業系統自帶的一款紙牌遊戲,遊戲規則是這樣的 只能將牌拖到比她大一的牌上面 a最小,k最大 如果拖動的牌上有按順序排好的牌時,那麼這些牌也跟著一起移動,遊戲的目的是將所有的牌按同一花色從小到大排好,為了簡單起見,我們的遊戲只有同一花色的10張牌,從a到10,且隨機的...

HDU1584 蜘蛛牌(區間dp)

蜘蛛牌是windows xp作業系統自帶的一款紙牌遊戲,遊戲規則是這樣的 只能將牌拖到比她大一的牌上面 a最小,k最大 如果拖動的牌上有按順序排好的牌時,那麼這些牌也跟著一起移動,遊戲的目的是將所有的牌按同一花色從小到大排好,為了簡單起見,我們的遊戲只有同一花色的10張牌,從a到10,且隨機的在一行...