t064 最勇敢的機械人

2022-05-22 04:48:15 字數 1516 閱讀 1189

time limit: 1 second

memory limit: 128 mb

【背景】

wind設計了很多機械人。但是它們都認為自己是最強的,於是,一場比賽開始了~

【問題描述】

機器人們都想知道誰是最勇敢的,於是它們比賽搬運一些物品。

它們到了乙個倉庫,裡面有n個物品,每個物品都有乙個價值pi和重量wi,但是有些物品放在一起會**,並且**具有傳遞性。

(a和b會**、b和c會**則a和c會**)機器人們可不想因此損失自己好不容易從wind那裡敲詐來的裝備,於是它們想知道在

能力範圍內,它們最多可以拿多少價值的物品。

你能幫助它們嗎? 

每組測試資料

第1行為n,wmax,k(0<=n,wmax,k<=1000)

接下來n行,為每個物品的pi,wi(0<=pi<=1000,1<=wi<=10,均為整數)

再接下來k行,每行2個數字a,b表示a和b會發生** 

對每組資料輸出1行

為最大可能價值 

3 10 1

100 1

200 5

10 5

1 2

210
【題解】

a和b會發生**。即a,b中只能選乙個。也即分組揹包問題。

首先,如果x和y會發生**就把x和y合併在一起(並查集),然後根據合併的情況構造出k組物品。每組中都只能選取乙個物品。

然後先for k組揹包。表示按照組的順序進行揹包的操作。

然後是for 容量。表示接下來為j容量選取乙個物品。

然後是for第k組物品中的具體每乙個物品。

因為先for的是容量。所以可以保證。只會選取第k組物品中的乙個物品。

最後輸出答案即可。

【**】

#include int fa[1001],n,wmax,k,c[1001],w[1001],f[1001],next[1001],first[1001],what[1001],num = 0;

int findfather(int x) //用來尋找根節點,同時路徑壓縮

int main()

for (int i = 1;i <= n;i++) //把所有的子節點指向根節點

findfather(i);

int bo[1001] = ; //用來標記某乙個物品是哪一組的物品

k = 0;

for (int i =1;i <= n;i++)

if (bo[fa[i]] == 0) //這是第一次出現第k組物品的處理方法

else //不是第一次出現則記錄就好 可以縮短**。。想縮短就縮吧。-> 鄰接表那段可以不用寫兩次

for (int i = 1;i <= k;i++) //進行分組揹包的操作

for (int j = wmax;j >= 0;j--)

temp = next[temp];}}

printf("%d",f[wmax]); //最後輸出答案。

return 0;

}

最勇敢的機械人

題目描述 wind設計了很多機械人。但是它們都認為自己是最強的,於是,一場比賽開始了 機器人們都想知道誰是最勇敢的,於是它們比賽搬運一些物品。它們到了乙個倉庫,裡面有n個物品,每個物品都有乙個價值pi和重量wi,但是有些物品放在一起會 並且 具有傳遞性。a和b會 b和c會 則a和c會 機器人們可不想...

最勇敢的機械人

時間限制 1000 ms 記憶體限制 128 mb 機器人們都想知道誰是最勇敢的,於是它們比賽搬運一些物品。它們到了乙個倉庫,裡面有n個物品,每個物品都有乙個價值pi和重量wi,但是有些物品放在一起會 並且 具有傳遞性。a和b會 b和c會 則a和c會 機器人們可不想因此損失自己好不容易從wind那裡...

vijos 1250 最勇敢的機械人

題目描述 wind設計了很多機械人。但是它們都認為自己是最強的,於是,一場比賽開始了 機器人們都想知道誰是最勇敢的,於是它們比賽搬運一些物品。它們到了乙個倉庫,裡面有n個物品,每個物品都有乙個價值pi和重量wi,但是有些物品放在一起會 並且 具有傳遞性。a和b會 b和c會 則a和c會 每個機械人的最...