AHOI2014 JSOI2014 騎士遊戲

2021-10-01 21:20:21 字數 1417 閱讀 6723

題目背景

長期的宅男生活中,jyy又挖掘出了一款rpg遊戲。在這個遊戲中jyy會

扮演乙個英勇的騎士,用他手中的長劍去殺死入侵村莊的怪獸。

題目描述

在這個遊戲中,jyy一共有兩種攻擊方式,一種是普通攻擊,一種是法術攻擊。兩種攻擊方式都會消耗jyy一些體力。採用普通攻擊進攻怪獸並不能把怪獸徹底殺死,怪獸的屍體可以變出其他一些新的怪獸,注意乙個怪獸可能經過若干次普通攻擊後變回乙個或更多同樣的怪獸;而採用法術攻擊則可以徹底將乙個怪獸殺死。當然了,一般來說,相比普通攻擊,法術攻擊會消耗更多的體力值(但由於遊戲系統bug,並不保證這一點)。

遊戲世界中一共有n種不同的怪獸,分別由1到n編號,現在1號怪獸入侵村莊了,jyy想知道,最少花費多少體力值才能將所有村莊中的怪獸全部殺死呢?

輸入格式

第一行包含乙個整數n。

接下來n行,每行描述乙個怪獸的資訊;

其中第i行包含若干個整數,前三個整數為si,ki和ri,表示對於i號怪獸,普通攻擊需要消耗si的體力,法術攻擊需要消耗ki的體力,同時i號怪獸死亡後會產生ri個新的怪獸。表示乙個新出現的怪獸編號。同一編號的怪獸可以出現多個。

輸出格式

輸出一行乙個整數,表示最少需要的體力值。

輸入輸出樣例

輸入 #1複製

44 27 3 2 3 2

3 5 1 2

1 13 2 4 2

5 6 1 2

輸出 #1複製

26有點dp的感覺,但是有後效性,所以沒辦法dp。

對於乙個怪物,很有可能是成環的。若a死後生成b,c。那麼a可以像最短路的三角不等式一樣,縮邊。

我們直接對所有點跑spfa,看是否可以鬆弛,然後如果可以鬆弛,那麼連向他的點因為這次鬆弛之後,也是可能鬆弛的,所以我們重複在放進佇列當中。

ac**:

#include

#define int long long

using namespace std;

const

int n=

2e5+

10,m=

1e6+10;

int n,d[n]

,k[n]

,s[n]

,vis[n]

,res; queue<

int> q;

int head[n]

,nex[m]

,to[m]

,tot;

vector<

int> g[n]

;inline

void

add(

int a,

int b)

void

spfa()

}}signed

main()

spfa()

; cout<

}

AHOI2014 JSOI2014 騎士遊戲

題目 思博貪心題寫了乙個半小時沒救了,我也沒看出這是乙個 spfa 來啊 設 dp i 表示徹底乾掉第 i 只怪物的最小花費,乙個非常顯然的事情,就是對於 k i 值最小的怪物滿足 dp i k i 非常好理解,反正到最後都要乾掉這個怪物,何必再把它乾成別的怪物 於是我們按照 k i 的值先排序一下...

AHOI2014 JSOI2014 騎士遊戲

傳送門 考慮 text 設 dp i 表示滅種 霧 乙隻編號為 i 的怪物的代價。那麼轉移顯然是 dp i min k i,s i sum dp 但是我們會發現這個東西是有後效性的。所以我們會想要用建圖然後跑乙個最短路什麼的來搞。於是我們觀察到上面那個 text 式子中,dp i 如果用後面那一項來...

AHOI2014 JSOI2014 宅男計畫

傳送門 我們首先要發現乙個性質 存貨天數隨買食物的次數的變化類似於單峰函式。具體證明不會啊,好像是二分加三分來證明?但是沒有找到明確的嚴格證明。感性理解一下就是 買的食物太少,很容易餓死 買太多就沒錢了,也活不長。所以我們考慮如何對於當前三分的答案如何 text 有乙個顯而易見的性質就是我們不會用 ...