description
玩過diablo的人對技能樹一定是很熟悉的。一顆技能樹的每個結點都是一項技能,要學會這項技能則需要耗費一定的技能點數。只有學會了某一項技能以後,才能繼續學習它的後繼技能。每項技能又有著不同的級別,級別越高效果越好,而技能的公升級也是需要 耗費技能點數的。
有個玩家積攢了一定的技能點數,他想盡可能地利用這些技能點數來達到最好的效果。因此他給所有的級別都打上了分,他認為效果越好的分數也越高。現在他要你幫忙尋找乙個分配技能點數的方案,使得分數總和最高。
input
第一行是乙個整數n(1<=n<=20),表示所有不同技能的總數。接下來依次給出n個不同技能的詳細情況。每個技能描述包括5行,第一行是該技能的名稱,第2行是該技能在技能樹中父技能的名稱,為空則表示該技能不需要任何的先修技能便能學習。第3行是乙個整數l(1<=l<=20),表示這項技能所能擁有的最高端別。第4行共有l個整數,其中第i個整數表示從地i-1級公升到第i級所需要的技能點數(0級表示沒有學習過)。第5行包括l個整數,其中第i個整數表示從第i-1級公升級到第i級的效果評分,分數不超過20。在技能描述之後,共有兩行,第1行是乙個整數p,表示目前所擁有的技能點數。接下來1行是n個整數,依次表示角色當前習得的技能級別,0表示還未學習。這裡不會出現非法情況。
output
s,表示最佳分配方案所得的分數總和。
sample input3
freezing arrow
ice arrow
33 3 3
15 4 6
ice arrow
cold arrow
24 3
10 17
cold arrow
33 3 2
15 5 2
100 0 1
sample output
它雖然說是樹,但是它輸入的有可能是乙個森林。因此,我們需要乙個編號為0的點,作為所有樹的根節點
if
(s!=
"")x=
find
(s);
else x=0;
son[x][0
]++;son[x]
[son[x][0
]]=a[i]
;
dp動態轉移
f[i][j]表示當前節點i用j點能量值可獲得的最大值
第一種:
當前已經有等級了,我們不去公升級它
if
(c[son[x]
[i]]!=0
)
第二種就是公升級它
long
long o1=
0,o2=0;
for(
int j=c[son[x]
[i]]+1
;j<=b[son[x]
[i]]
;j++
)
另外因為在公升級時f[i][j]的值會改變,就不能直接賦給兒子,所以要間接轉移
for
(int j=
0;j<=k;j++
)o[j]
=f[x]
[j];
#include
#include
using
namespace std;
long
long x,n,p,tot,a[
1005
],b[
1005
],c[
1005
],f[
1005][
1005
],b1[
1005][
1005
],b2[
1005][
1005
],son[
1005][
1005];
string s,s1[
1005];
intfind
(string s)
voiddp(
int x,
int k)
long
long o1=
0,o2=0;
for(
int j=c[son[x]
[i]]+1
;j<=b[son[x]
[i]]
;j++)}
}int
main()
cin>>p;
for(
int i=
1;i<=n;i++
) cin>>c[a[i]];
dp(0,p)
; cout<[p];
return0;
}
技能樹 difficult 樹形DP
time limit 1000ms memory limit 65536k total submit 18 accepted 11 description 玩過d ia bl odiablo diablo 的人對技能樹一定是很熟悉的。一顆技能樹的每個結點都是一項技能,要學會這項技能則需要耗費一定的技...
DP 樹形 DP 樹的中心
做法 a 大致想法是進行兩遍dfs,找到每個節點的向下的最長路徑 di 和向上的最長路徑 ui 然後列舉每乙個點,再找到min max di ui b 補充細節 1 根據樹的直徑求法,向下求的時候會有乙個最大值和次大值,例如節點 i 的 d1i d2i,當更新 i 的某個子節點 j 的 uj 時候,...
樹形dp 樹的重心
1.只需要求出最大子樹中節點數最小的數目即可 題意 有乙個國王要把他的領土分給兩個兒子,國王的領土是一棵樹,n個結點,n 1條邊把這些結點連起來,現在大小兒子要選擇乙個點作為他的首都,那麼除首都分別是這兩個兒子之外,其他的城市 結點 根據離誰近就歸誰所有,如果一樣遠的話就歸大兒子所有,現在假設兩個人...