plants vs. zombies(pvz)是最近十分風靡的一款小遊戲。plants(植物)和zombies(殭屍)是遊戲的主角,其中plants防守,而zombies進攻。該款遊戲包含多種不同的挑戰系列,比如protect your brain、bowling等等。其中最為經典的,莫過於玩家通過控制plants來防守zombies的進攻,或者相反地由玩家通過控制zombies對plants發起進攻。
現在,我們將要考慮的問題是遊戲中zombies對plants的進攻,請注意,本題中規則與實際遊戲有所不同。遊戲中有兩種角色,plants和zombies,每個plant有乙個攻擊位置集合,它可以對這些位置進行保護;而zombie進攻植物的方式是走到植物所在的位置上並將其吃掉。
遊戲的地圖可以抽象為乙個n行m列的矩陣,行從上到下用0到n–1編號,列從左到右用0到m–1編號;在地圖的每個位置上都放有乙個plant,為簡單起見,我們把位於第r行第c列的植物記為pr, c。
plants分很多種,有攻擊類、防守類和經濟類等等。為了簡單的描述每個plant,定義score和attack如下:
score[pr, c]
zombie擊潰植物pr, c可獲得的能源。若score[pr, c]為非負整數,則表示擊潰植物pr, c可獲得能源score[pr, c],若為負數表示擊潰pr, c需要付出能源 -score[pr, c]。
attack[pr, c]
植物pr, c能夠對zombie進行攻擊的位置集合。
zombies必須從地圖的右側進入,且只能沿著水平方向進行移動。zombies攻擊植物的唯一方式就是走到該植物所在的位置並將植物吃掉。因此zombies的進攻總是從地圖的右側開始。也就是說,對於第r行的進攻,zombies必須首先攻擊pr, m-1;若需要對pr, c(0≤c在本題的設定中,plants的攻擊力是無窮大的,一旦zombie進入某個plant的攻擊位置,該zombie會被瞬間消滅,而該zombie沒有時間進行任何攻擊操作。因此,即便zombie進入了乙個plant所在的位置,但該位置屬於其他植物的攻擊位置集合,則zombie會被瞬間消滅而所在位置的植物則安然無恙(在我們的設定中,plant的攻擊位置不包含自身所在位置,否則你就不可能擊潰它了)。
zombies的目標是對plants的陣地發起進攻並獲得最大的能源收入。每一次,你可以選擇乙個可進攻的植物進行攻擊。本題的目標為,制定一套zombies的進攻方案,選擇進攻哪些植物以及進攻的順序,從而獲得最大的能源收入。
輸入格式:
輸入檔案pvz.in的第一行包含兩個整數n, m,分別表示地圖的行數和列數。
接下來n×m行描述每個位置上植物的資訊。第r×m + c + 1行按照如下格式給出植物pr, c的資訊:第乙個整數為score[pr, c], 第二個整數為集合attack[pr, c]中的位置個數w,接下來w個位置資訊(r』, c』),表示pr, c可以攻擊位置第r』 行第c』 列。
輸出格式:
輸出檔案pvz.out僅包含乙個整數,表示可以獲得的最大能源收入。注意,你也可以選擇不進行任何攻擊,這樣能源收入為0。
輸入樣例#1:
3 210 0
20 0
-10 0
-5 1 0 0
100 1 2 1
100 0
輸出樣例#1:
25
約20%的資料滿足1 ≤ n, m ≤ 5;
約40%的資料滿足1 ≤ n, m ≤ 10;
約100%的資料滿足1 ≤ n ≤ 20,1 ≤ m ≤ 30,-10000 ≤ score ≤ 10000
有點像一道拓撲排序刪環的題目——攝像頭,也像noip2015d1t2資訊傳遞,拓撲排序刪環之後,這題是最大權閉合子圖。刪點不說了。
最大權閉合子圖可以看這篇博文,就像太空旅行計畫那題,吃乙個正分的植物相當於做乙個實驗盈利,吃乙個負分的植物相當於花錢帶乙個儀器。要吃乙個植物,就要把保護它的都先吃掉,就相當於要做乙個實驗就要把所需的儀器全花錢買下。
#include#include#include
#include
#include
intn,m;
int score[1000]=;
inline
int id(int x,int
y)struct
tppointp[
1000
];bool usable[1000]=;
void del(intu)}
ints,t;
struct
edgee[
3000000
];int head[1000]=,cnt=2
;void add(int u,int v,intf);
head[u]=cnt++;
e[cnt]=;
head[v]=cnt++;
}int dis[1000
];bool
bfs()
}return dis[t]!=0;}
int dfs(int u,int
f)
if(flow_sum==0) dis[u]=-1
;
return
flow_sum;
}int
dinic()
return
ans;
}int
main()
for(int i=1;i<=n;i++)}}
for(int i=1;i<=n*m;i++)
if(p[i].ru==0&&!usable[i]) del(i);
long
long sum=0
;
for(int i=1,num=n*m;i<=num;i++)
}sum-=dinic();
if(sum<0) printf("
0\n"
);
else printf("
%lld\n
",sum);
return0;
}
洛谷 P1565 牛宮
題目 牛宮 思路 咳咳,先放個提交記錄 嗯再來個mjy0724的思路 然後就沒我什麼事了 有這麼幾點需要注意的地方 1 vector一定不能作為引數傳進函式,會t到飛起,親測100 50 2 第一列數要單獨判斷 3 字首和的處理,i,j 的字段和大於0的條件是sum j sum i 1 而非sum ...
洛谷P1565 牛宮
ap 神牛準備給自己蓋一座很華麗的宮殿。於是,他看中了一塊n m 的矩形空地。空地中每個格仔都有自己的海拔高度。ap 想讓他的宮殿的平均海拔在海平面之上 假設 海平面的高度是0,平均數都會算吧?而且,ap 希望他的宮殿盡量大,能夠容納更 多的人來膜拜他。請問ap 的宮殿最後會有多大?輸入格式 第一行...
洛谷P1565牛宮
傳送門 題目點這裡 首先理解題目,就是要求給定矩陣中權值和不小於零的最大子矩陣,資料範圍200也還不算棘手,暴力n 4的演算法也可以水到50分。正解要用到單調棧配合二分和字首和,複雜度n 3logn,跑得也還算快。分析一下,首先用乙個陣列a i j 記錄下第 i 行前 j 個元素之和,然後開始乙個個...