日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

学校测试-2015-03-01

發(fā)布時間:2025/3/15 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 学校测试-2015-03-01 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

記得以前做N皇后問題見到過二進制+位運算優(yōu)化的方法, 今天的搜索題第三題和第四題都可以用到二進制和位運算. 就只做了這兩個題目.


題目三

描述

傳遞游戲(pass)

Description
n個人在做傳遞物品的游戲,編號為1-n。
游戲規(guī)則是這樣的:開始時物品可以在任意一人手上,他可把物品傳遞給其他人中的任意一位;下一個人可以傳遞給未接過物品的任意一人。
即物品只能經(jīng)過同一個人一次,而且每次傳遞過程都有一個代價;不同的人傳給不同的人的代價值之間沒有聯(lián)系;
求當物品經(jīng)過所有n個人后,整個過程的最小總代價是多少。
Input Format
第一行為n,表示共有n個人(16>=n>=2);
以下為n*n的矩陣,第i+1行、第j列表示物品從編號為i的人傳遞到編號為j的人所花費的代價,特別的有第i+1行、第i列為-1(因為物品不能自己傳給自己),其他數(shù)據(jù)均為正整數(shù)(<=10000)。
Output Format
一個數(shù),為最小的代價總和。


分析

  • 狀壓DP, 二進制表示狀態(tài)(點到過或沒到過), 位運算實現(xiàn)查找和更新等操作
  • f[i][k]表示狀態(tài)為 k 并且最后停留在 i 點時的最小代價
  • => min{f[i][(1<<n)+1], (0<=i<n)}
  • 轉(zhuǎn)移 :
    枚舉狀態(tài) k : 0 -> (1 << n) - 1
    枚舉要更新的結(jié)點 i : 0 -> n-1
    枚舉中間結(jié)點 j : 0 -> n-1, (i != j)
    如果滿足 在狀態(tài) k 中第 i 的位置為 0, 而第 j 的位置為 1, 那么就可以用 j 去更新 i.
  • 核心 :

    if(i != j && (k&(1 << j)) && !(k&(1 << i))) f[i][k^(1 << i)] = min(f[i][k^(1 << i)], f[j][k] + d[j][i]);
  • 初始化
    f[i][1 << i] = 0, (0<=i<n)
    表示從任意點出發(fā)


代碼

https://code.csdn.net/snippets/609746


題目四

描述

皇后守衛(wèi)(queen)
Description
給一個N * M的棋盤,棋盤上的有些格子被打上了標記?,F(xiàn)在需要在其中放置盡量少的皇后,使得所有被打上標記的格子至少被某一個皇后攻擊或占據(jù)到。皇后之間可以互相攻擊。
Input Format
輸入最多15組數(shù)據(jù)。
每組數(shù)據(jù)第一行包含兩個整數(shù)N和M(1 < N, M < 10),以下為一個N行M列的棋盤,其中打上標記的格子用‘X’表示,其它格子用‘.’表示。
輸入以一個0結(jié)尾。
Output Format
對于每組數(shù)據(jù),輸出一個數(shù)表示最少需要使用的皇后數(shù)目。


分析

  • 二進制+位運算優(yōu)化+普通最優(yōu)化剪枝的 dfs
  • void dfs(int x, int row, int ld, int rd, int* k, int c)
    x => 當前行
    k => 數(shù)組, 表示當前所有被覆蓋的位置, 每一行都是用二進制表示的, 所以數(shù)組只需開一維
    c => 計數(shù)變量, 已經(jīng)放的皇后數(shù)
    主函數(shù)調(diào)用dfs(0, 0, 0, 0, k, 0) // k 初始化全為 0
  • 函數(shù)執(zhí)行過程
    如果該狀態(tài)下滿足了需要, 直接更新答案后返回
    如果所以行已經(jīng)考慮完了(x >= n), 直接返回
    最優(yōu)化剪枝 : 如果當前 c 不比已經(jīng)記錄的 ans 更優(yōu), 直接返回
    從當前行中選可以放置皇后的地方開始放皇后, 繼續(xù)dfs到下一層
    該行不放皇后, dfs到下一層
  • 許多精巧的位運算 :

    • 判斷是否滿足條件, 標記的地方都被覆蓋到
      枚舉 x, 如果所有 (k[x]&tar[x]) == tar[x] 說明滿足
      解釋 : tar[x]表示第 x 行需要被覆蓋的二進制狀態(tài). 只有當 tar[x] 為 1 的地方 k[x] 也為 1 才滿足
    • 更新狀態(tài), 在第 x 行二進制下 p 位置放置皇后對原可覆蓋狀態(tài) k 的影響
    void update(int x, int p, int* k) { k[x] = upperlim; for(int i = 1; x-i >= 0; i++) {if((p<<i) < upperlim) k[x-i] |= (p<<i);if((p>>i) > 0) k[x-i] |= (p>>i);k[x-i] |= p; } for(int i = 1; x+i < n; i++) {if((p<<i) < upperlim) k[x+i] |= (p<<i);if((p>>i) > 0) k[x+i] |= (p>>i);k[x+i] |= p; } }

    解釋 : upperlim = (1 << n) - 1
    首先 x 行應(yīng)該全變?yōu)?1, 也就是 k[x] 狀態(tài)為 upperlim
    再考慮對角線和列
    對p的解釋 : p 的二進制中只有一位為 1, 也就是皇后所在列的那一位

  • 其他
    • ans 可以初始化為 5
      在 9*9 全 ‘X’ 的棋盤上
    • 皇后可以互相攻擊, 也就是同一行上可以有多個皇后

代碼

https://code.csdn.net/snippets/609744



總結(jié)

以上是生活随笔為你收集整理的学校测试-2015-03-01的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。