1195 最小總代價

2021-10-07 04:06:22 字數 2174 閱讀 5771

題目描述

n個人在做傳遞物品的遊戲,編號為1-n。

即物品只能經過同乙個人一次,而且每次傳遞過程都有乙個代價;不同的人傳給不同的人的代價值之間沒有聯絡;

求當物品經過所有n個人後,整個過程的總代價最小是多少。

輸入

第一行為n,表示共有n個人(16>=n>=2);

以下為n*n的矩陣,第i+1行、第j列表示物品從編號為i的人傳遞到編號為j的人所花費的代價,特別的有第i+1行、第i列為-1(因為物品不能自己傳給自己),其他資料均為正整數(<=10000)。

(對於50%的資料,n<=11)。

輸出

乙個數,為最小的代價總和。

樣例輸入

2-1

9794

2724

-1

樣例輸出

2724
資料範圍限制提示50% n<=11

思路:

狀態壓縮 dp 是一種針對集合的 dp,可以用乙個整數對應的二進位制數表示乙個集合,用這個集合來表示當前的狀態,通過位運算來轉移狀態。與普通 dp 相比,狀態壓縮 dp 的轉移狀態比較複雜,由於一些特點可以使用乙個二進位制數來表示,從而達到了壓縮狀態的效果,其在 dp 思路上與普通 dp 基本類似。

狀壓dp運用到一些位運算,大致如下:

關於位運算的高階:

三種常用的操作:

判斷x的第i位是否為1 if( x&(1<

將x的第i位改為1 x=x|1<

將x的最低位1去掉 x=x&(x-1);

回到本題……

題目大意:有n個人在傳球,可以從任意乙個人開始,任何乙個未接球的人,都可以作為下乙個接球的人,每兩個人之間傳球需要花費一些代價,問所有人都接到過球後的最小代價。

設f[st][i]表示當前狀態為st下,以i為當前的最後接球人的最小代價。

初始狀態: f[1所有的狀態的區間為1~(1當然必須這個人要是拿過球的,即(1<

j作為當前的最後持球人,他才能繼續往下傳,下乙個接球的人顯然也必須有乙個條件:他沒有接過球,即(1狀態轉移方程:f[i

∣(1<

][k]

=min

(f[i

∣(1<

][k]

,f[i

][j]

+a[j

][k]

);f[i|(1

i∣(1

<

][k]

=min

(f[i

∣(1<

][k]

,f[i

][j]

+a[j

][k]

);第i個狀態時,最後持球人為j,將球傳給了k,那麼新狀態為i|(1傳球結束後,這個狀態(1

#include

#include

#include

#include

#include

#include

#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);

using

namespace std;

const

int max=

2147483647

;const

int n=

1e6;

int n,a[20]

[20],f[

1<<17]

[17],ans=max;

intmain()

vijos1456 最小總代價

描述 n 個人在做傳遞物品的遊戲,編號為1 n。遊戲規則是這樣的 開始時物品可以在任意一人手上,他可把物品傳遞給其他人中的任意一位 下乙個人可以傳遞給未接過物品的任意一人。即物品只能經過同乙個人一次,而且每次傳遞過程都有乙個代價 不同的人傳給不同的人的代價值之間沒有聯絡 求當物品經過所有 n 個人後...

Vijos 最小總代價 狀壓DP

描述 n個人在做傳遞物品的遊戲,編號為1 n。即物品只能經過同乙個人一次,而且每次傳遞過程都有乙個代價 不同的人傳給不同的人的代價值之間沒有聯絡 求當物品經過所有n個人後,整個過程的總代價是多少。格式 輸入格式 第一行為n,表示共有n個人 16 n 2 以下為n n的矩陣,第i 1行 第j列表示物品...

狀態壓縮動態規劃 最小總代價

乙個包含n個元素的集合,該集合的子集可以表示為從0 00 2n 12 n 1 2n 1 的是乙個十進位制整數。例如 一共有5個人,第0 3個人被選擇,就用 01001 2 01001 2 01001 2 表示,那麼該子集對應的十進位制數為9。此謂狀態壓縮。把傳遞過物品的人的集合壓縮為乙個整數i,用i...